getting data from express server with angular 2 - javascript

I'm trying to build a small facebook login with angular 2 but well I'm having problem, after logging in the facebook the user would be redirected to /home
app.get('/home', function (req, res) {
res.sendfile(path.join(__dirname, '../', 'views', 'index.html'), { user: req.user});
console.log({ user: req.user});
});
I'm trying to display the user information in angular2 page but I keep getting undefined. console logging the object works fine.
I used the same method with ejs files using res.render
and using this inside the ejs
<%= user.facebook.name %>
and it works fine. I tried to use {{}} in the angular 2 but not working.
any help please?
thanks

I would define this element when bootstrapping your application. Because this hint is only available within your index.html page, I would use the following processing.
Update the file that bootstraps your application:
import {bootstrap} from '...';
import {provide} from '...';
import {AppComponent} from '...';
export function main(facebookUser) {
bootstrap(AppComponent, [
provide('user', { useValue: facebookUser })
]);
}
Provide this value from the index.html file this way:
<script>
var facebookUser = '<%= user.facebook.name %>';
System.import('app/main').then((module) => {
module.main(facebookUser);
});
</script>
This question could interest you:
Pass Constant Values to Angular from _layout.cshtml

ok thanks for the replies i found the answer for my question. this code will call the api that and get the user details
constructor(private http: Http) { }
ngOnInit() {
this.getUser();
}
getUser() {
this.http.get('/api/user')
.map((res:Response) => res.json())
.do(data => console.log('data: ' + JSON.stringify(data)))
.subscribe(
data => { this.user = data.user.facebook.name},
err => console.error(err),
() => console.log('done')
);
}

Related

Read data from file and use it on Angular ssr and csr

I have a config file and I want to use it without HTTP request on angular SSR and then somehow send data to CSR and use it on that too, this config file is a list of links that I want to use in website footer and be able to change them without rebuilding the project or making HTTP request.
The solution I tryed is to read from the config file every 1 hour in server.ts like this:
fs.readFile('./src/skills.txt', 'utf8', (err, data) => {
console.log('updated skills');
if (err) {
console.error(err);
return;
}
if(data) {
skills = data;
}
});
But then for sending this data to response all I could think about which is not really a good way of doing it I guess is to loop around this file and create my output HTML and then replace a key I put in footer HTML with it in returned html as bellow:
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] }, (err, html) => {
if(skills) {
html = html.replace('#skills_placeholder',skills);
}
res.send(html);
});
This way I have the output I need in SSR response but I also want to have this response on CSR when user is logged in. I tryed to add an element with and id and select it on CSR but its undefined, Tryed example :
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] }, (err, html) => {
if(skills) {
html = html + '<span class="d-none" id="perfectlancer_skills">' + skills + '</span>';
}
res.send(html);
});
And then on CSR I tryed:
this.doc.getElementById('perfectlancer_skills'.innerHTML
but it is undefined althoght it exists on SSR response;

Can't get axios to perform get without full url

Every time I try to use /bikes or /bikes/add in my axios requests, it never seems to connect. I always get something like this:
xhr.js:178 GET http://localhost:3000/bikes/ 404 (Not Found)
However, when I use the full url, like: http://localhost:4000/bikes/ it connects perfectly. I tried messing with the app.get in server.js, the get in my route file, and the actually axios.get in my bikes-list file to no avail.
Anyone have any ideas? This is part of a MERN app.
bikes-list.js(component) snippet:
componentDidMount() {
axios.get('/bikes/')
.then(response => {
this.setState({bikes: response.data});
})
.catch(function (error){
console.log(error);
})
}
server.js snippet:
app.use('/bikes', bikeRoutes);
bikes.js(route) snippet:
router.get('/',function(req, res) {
Bikes.find(function(err, bikes) {
if (err) {
console.log(err);
} else {
res.json(bikes);
}
}); });
Thanks!
maybe the cause is that you are not using the right port when using /bikes? One solution is to create a small module like this:
// client.js
var axios = require('axios');
var axiosInstance = axios.create({
baseURL: 'http://localhost:4000',
/* other custom settings */
});
module.exports = axiosInstance;
and then use this new module in your code instead of requiring axios
directly:
var client = require('./client');
client.get('relative/path')

Using Angular, ExpressJS, NodeJS to download a text Document with a button

I am trying to create a download button, which enables the user to download a document from my node.js server.
Here's the fancy button:
I am using Angular as a front-end framework and node.js and express.js for the backend.
This is the document I would like the user to be able to download:
So for the backend I wrote this code:
server.js
const bodyParser = require('body-parser');
const cors = require('cors')
const express = require('express');
const app = express();
const router = express.Router();
const path = require('path');
app.use(cors());
app.use(bodyParser.json());
router.route('/generateReportByGet').get((req, res) => {
res.download(path.join(__dirname, 'docs/doc1.txt'), function (err) {
if (err) {
console.log(err);
} else {
console.log('%c%s', 'color: #f2ceb6', 'NO ERROR');
console.log('%c%s', 'color: #00a3cc', res);
}
});
});
app.use('/', router);
app.listen(5353, () => console.log('Express server running on port 5353'));
After running the server.js file, and typing:
localhost:5353/generateReportByGet
The file gets downloaded:
So here's what my logic told me:
Create a button with Angular that sends a GET request to that same
adress and I should get the same result: The file gets downloaded.
So my first question is : Is my logic flawed?
So here's the front-end code:
app.component.html:
<button color="primary" (click)="generateReportbyGet()">Generate report By Get</button>
<router-outlet></router-outlet>
app.component.ts:
import { Component } from "#angular/core";
import { GenerateReportService } from "./services/generate-report.service";
#Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
constructor(private generateReportService: GenerateReportService) {}
generateReportbyGet() {
this.generateReportService.generateReportbyGet().subscribe((results) => {
console.log("generateReportbyGet ...");
console.log('%c%s', 'color: #aa00ff', results);
}
}
generate-report.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class GenerateReportService {
uri = 'http://localhost:5353';
constructor(private http: HttpClient) {}
generateReportbyGet() {
return this.http.get(`${this.uri}/generateReportByGet`, {responseType: 'text'});
}
}
I thought this should work as I described. However, when I click on the button nothing happens.
But, on the browser console, I am able to retrieve the text from the file:
So here's my second question:
2/ Why doesn't the file downloading process get started when I click on the button? Is it a problem with the code or the GET request logic?
Thank you!!
In your Node JS server side code... you're reading the contents of the file and sending them...
(1) to return a file, you can do a:
app.get('/generateReportByGet', function (req, res) { res.sendFile(__dirname + "/" + "docs/doc1.txt"); })
(2) or you can do a (as per this):
app.get('/generateReportByGet', function(req, res){
const file = `${__dirname}/docs/doc1.txt`;
res.download(file);
});
File can't be downloaded making ajax call.
In your component service change below code.
generateReportbyGet() {
var link=document.createElement('a');
link.href=`${this.uri}/generateReportByGet`;
link.download="MyDoc.txt";
link.click();
}

How to restrict page access to unlogged users with VueJS?

I'm currently practicing VueJs and making some sample apps. i'm making a very simple app that is basically just a login page where users will put their credentials and access their profile. However I can't think of a way to restrict view to the profile section if the user isn't logged (i.e that they try to access by manually changing the url to /profile)
The app is pretty barebones, it's just using JS and bootstrap.
Is there a way to immediately redirect users back to the login screen if they're not logged and try to access the profile page?
You can use https://router.vuejs.org/guide/advanced/navigation-guards.html beforeEach to check if the current user is logged or not and do what you need to do :).
your routes:
...
{
path:'/profile',
meta:{guest:false},
component:ProfileComponent
},
...
example :
router.beforeEach((to, from, next) => {
if (!to.meta.guest) {
// check if use already logged
// if true then go to home
return next({path:'/'}); // '/' is home page for example
// else then continue to next()
}
return next();
});
You can use also beforeEnter param if you have only few routes which should be protected.
routes.js
import {ifAuthenticated} from "../middleware/authentication";
{
path: '/test',
name: 'Test',
component: Test,
beforeEnter: ifAuthenticated
},
authentication.js
import store from '../../store'
export const ifAuthenticated = (to, from, next) => {
store.dispatch('User/getUser')
.then(() => {
next()
})
.catch(() => {
next({ name: 'Login', query: { redirect_to: to.fullPath } })
})
}
Example with usage of vuex.

Express Session property differentiates between browser and Postman

UPDATE
I think it's worth mentioning I am running Angular CLI which runs on port 4200 and my server is running on port 8080. Could this be a problem? It's the only thing I can think of at the moment
When I make a call to my route '/auth/login' I set a loggedIn property on the session object. To check a user is authenticated, a request is made to '/auth/checktoken'. In here, I check for the presence of the loggedIn property on the req.session object. When I do these requests within Postman everything works perfectly fine, but when using the browser my session.loggedIn property is undefined. I will paste the relevant code below. Thanks in advance for any help
Server Side
router.get('/checktoken', (req, res) => {
if(!req.session.loggedIn) {
return res.status(401).send({
userTitle: 'Not authorised',
userMessage: 'You are not authorised to view this'
})
}
return res.status(200).send()
})
Client Side
#Injectable()
export class CheckAuthenticationService implements CanActivate {
constructor(
private router: Router,
private http: HttpClient) { }
canActivate() {
this.http.get('http://localhost:8080/auth/checktoken', { responseType: 'text' })
.toPromise()
.then(() => {
this.router.navigate(['admin']);
})
.catch( () => {
this.router.navigate(['login']);
});
return true;
}
}
Snippet of login code that sets the loggedIn property
if (user) {
user.comparePassword(password, (err, isMatch) => {
if (isMatch && isMatch) {
req.session.loggedIn = user;
res.status(200).send()
} else {
res.status(404).send({
userTitle: 'Wrong password',
userMessage: 'Please make sure your password is correct'
});
}
});
}
Session Store setup
app.use(session({
name: 'jack-thomson',
secret: SECRET_KEY,
saveUninitialized: false,
resave: true,
store: new MongoStore({
mongooseConnection: mongoose.connection
})
}))
This all works in Postman but when hitting these endpoints on the client, .loggedIn is undefined, always
I had the same problem before. I think it's about cors credential. I use Axios on React to POST data login to my Express backend application. I need to add these lines:
import axios from 'axios';
axios.defaults.withCredentials = true;
Then on my Express project, I add cors:
var cors = require('cors');
app.use(cors({
credentials: true,
origin: 'http://localhost:3000' // it's my React host
})
);
Finally I can call my login function as usual, for instance:
signup(){
var url = 'http://localhost:3210/'
axios.post(url, {
email: this.refs.email.value,
username: this.refs.username.value,
password: this.refs.password.value,
passwordConf: this.refs.passwordConf.value
})
.then((x)=>{
console.log(x);
if(x.data.username){
this.setState({statusSignup: `Welcome ${x.data.username}`});
} else {
this.setState({statusSignup: x.data});
}
})
.catch((error)=>{console.log(error)})
}
login(){
var url = 'http://localhost:3210/';
var data = {
logemail: this.refs.logemail.value,
logpassword: this.refs.logpassword.value,
};
axios.post(url, data)
.then((x)=>{
console.log(x);
if(x.data.username){
this.setState({statusLogin: `Welcome ${x.data.username}`});
} else {
this.setState({statusLogin: x.data});
}
})
.catch((error)=>{console.log(error)})
}
And it works! Hope this solve your problem.
Are you using CORS?
I had the same problem, and i solved it by putting { withCredentials: true } as optional arguments in every request.
I mean whenever you send a http/https request in your service, put this as last argument, and you are good to go.
You can read this and this Stackoverflow question for more information on the topic.
I have finally figured out what is going on. My Angular CLI was running on 4200 and my server was running on a separate port. I have gotten over the issue with serving my application with express so it is all one one route. This has solved the issue for me. If anyone comes by this I hope this information comes in handy to you!

Categories

Resources