angularjs express get data back via $http post - angularjs

I am newbie in firebase admin SDK and trying to get it work on my angularjs app, using and following the steps here and this here:
I have correctly setup my firebase admin SDK and initialized it like this in server.js file on my node server:
var admin = require("firebase-admin");
var serviceAccount = require("path/to/serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
});
app.post('/.firebase-user', function (req, res, nex) {
admin.auth().getUser(req.body.uid)
.then(function (userRecord) {
// See the tables below for the contents of userRecord
console.log("Successfully fetched user data:", userRecord.toJSON());
})
res.status(200).send({data: userRecord.toJSON()});
return nex();
.catch(function (error) {
console.log("Error fetching user data:", error);
res.status(117);
return nex();
});
});
now I want to access userRecord.toJSON() inside my controller:
$http.post('/.firebase-user', {uid: firebase.auth().currentUser.uid})
.then(function(response) {
console.log($scope.data, response.userRecord);
});
But it is not printing the userRecord.toJSON(), instead I get true undefined in the console.
Please help me to fetch the info back inside my app. thanks

It looks like there are a few issues with your (Express) app request handler:
In your Angular code, you make a request to the /.fb endpoint but in your server code you are listener on the /.firebase-user endpoint. I assume you want these to both be the same.
Your server code never actually sends a response to the Angular code. I'm surprised your then() completion handler ever actually completes. You should need to explicitly send a response with something like res.status(200).send(userRecord.toJSON()) in the success case and res.status(400).send({ error: error }) in the error case.
You should add a catch() to your Angular code to ensure you are catching any errors or failed requests being made by the server code.

Related

Ionic + Passport isAuthenticated() returns false

I have my app in angularJs 1.6 built with MEAN stack working well, i'm using passport for authentication.
When I decide to test it with ionic, the app itself works well (files are basically identical) but the authentication with passport is broken
I can register and login a user, but when I want to check if the user is logged by using req.isAuthenticated() on my server, it always answers false.
I think it's because when I make a request from my normal angular app, the request contains a user object with password and email, but when I do from my ionic app, the user is missing
I've spend the day working on it, any help would be great !
EDIT 1:
Sorry for not including code, it's my first experience here
My login route + my function for login
app.post('/api/login', login);
function login(req, res, next) {
//console.log(req);
passport.authenticate('local-login', function(err, user, info) {
if (err) {
return next(err); // will generate a 500 error
}
// Generate a JSON response reflecting signup
if (! user) {
return res.send({success : 'false', message : req.flash('loginMessage') });
}
req.login(user, function(err) {
if (err) { return next(err); }
//console.log(req);
return res.send({success : 'true', message : req.flash('loginMessage') });
});
})(req, res, next);
}
The problem is, req.login is executed and I get a success: true, but with the ionic/cordova app, nothing seems to be memorized
After that, when I try to check if the user is logged with this
app.get('/api/login/loggedin', function(req, res) {
res.send(req.isAuthenticated() ? req.user : '0');
});
I always get '0', I think it is because cordova/ionic app cannot use cookies (the difference between requests is also the lack of cookie from the ionic one), but I can't understand how to manage a solution that works both with my web angular app and it's ionic version (still with passport)
Solution I just found:
In fact, it was a CORS problem because I don't know exactly why but Ionic/cordova didn't put {user:...} informations in the post request
Simply add
var cors = require('cors');
app.use(cors({origin: 'http://localhost:8100', credentials: true}));
to your server, it allows req to contains informations needed
and add
{withCredentials: true}
to all of your requests that are going to be checked with isAuthenticated(). For example:
$http.get('http://localhost:8081/api/todos', {withCredentials: true});
So the request sent contains the {user:...} part
I don't exactly know why you need to authorize it both in client and server side but it works fine

Requests API in React-boilerplate

I am using the boilerplate on https://github.com/react-boilerplate/react-boilerplate . The problem is that when I'm hitting API's It's returning error 404. I'm not able to get from where it is setting up the host (which is always going localhost).
no CORS error is also coming up on browser.
Prior to this I was working on create-react-app, there I simple put a "proxy" property in package.json and everything worked fine.
Today I set up this boilerplate for the first time and I would say it's a lil confusing _:)
You can specify API base url like this:
const API = process.env.NODE_ENV !== 'production' ? 'http://google.com' : 'http://localhost:5000'
So in development it will always point to localhost and in production it will point to other your prod server.
For people still searching,
all you need is to create something like this in server/index.js
app.get('/api/user', (req, res, next) => {
let parsedBody = JSON.parse(req.body)
res.send({ express: 'Hello From Express.' });
});
on client side request to /api/user
axios.get(`/api/user`)
.then(function (response) {
console.log("/api/user response", response);
})
.catch(function (error) {
console.log(error);
});
cheers

How to best handle errors in ExpressJS POST routes

I am currently struggling with best practices for error handling in ExpressJS routes, particularly POST routes.
I have set up the default middleware error handling and I am using return next(err); in case of any errors. This works fine for all errors in GET routes.
However, what is the best practice to handle errors in the other route types, in particular POST routes?
On the front end, I am using AngularJS and I am posting using $http. When using return next(err); in the POST route, the .error(function(data,status,headers,config) of $http is called (AngularJS) and I receive the whole html error page inside data variable.
What I am looking for is a redirect for the user to the general error page through the ExpressJS middleware in case the client-side should not handle this error. This way, I could also do my error handling and logging at one single place.
So, my current idea: In POST routes, simply do return res.status(500).send({err: err}); In case the application cannot recover, then use a redirect on client side with AngularJS to a general error page. However, I would prefer to use the ExpressJS middleware to have a central place to handle errors.
I appreciate any help or pointers to best practice articles!
For reference, the (standard) error middleware function looks like this:
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('shared/error/error', {
message: err.message,
error: err
});
});
If you're using an angular $http method to GET or POST to your server, you should be returning JSON data back to the app to parse. For example, your route:
app.get('/example', function(req, res) {
getSomeData()
.then(function(data) {
res.status(200).json(data);
}, function(err) {
res.status(400).json(err);
});
});
In your angular service, you can create a method that returns the route's data in a promise:
angularApp.service('DataService', function($http) {
this.getData = function() {
return $http.get('/example')
};
});
Then use the service in your controller like this:
angularApp.controller('MyController', function($scope, DataService) {
DataService.getData()
.then(function(response) {
$scope.data = response.data;
}, function(err) {
showErrorMessage(err.statusText);
});
});

Unable to get a JSON response from my express router using node-Fetch module

So I'm making a post request to my Express search router where I'm using the node-fetch module to call a remote api:
var fetch = require('node-fetch');
router.route('/search')
//Performs Job Search
.post(function(req, res){
var area = req.body.area;
fetch('https://api.indeed.com/ads/apisearch?publisher=*********&l=' + area)
.then(function(res) {
return res.json();
}).then(function(json) {
console.log(json);
});
})
I'm using angular 1 on the client side to call the router and parse the returned json:
$scope.search = function(){
$http.post('/api/search', $scope.newSearch).success(function(data){
if(data.state == 'success'){
//perform JSON parsing here
}
else{
$scope.error_message = data.message;
}
});
}
I'm just starting out with the MEAN stack and only have a vague idea of how promises work. So my issue is that my angular search function is not getting the JSON string I want to return from my remote API call. But rather the data parameter is getting set to my page html. Eventually the breakpoints I've set in the .then() clauses are hit and my json is returned. So my question is how can I use Anguular to get the JSON values when they are finally returned????
Can you try something like this?
router.route('/search')
//Performs Job Search
.post(function(req, res){
var area = req.body.area;
fetch('https://api.indeed.com/ads/apisearch?publisher=*********&l=' + area)
.then(function(result) {
res.json(result);
//or possibly res.send(result), depending on what indeed responds with
})
})
Turns out I had forgotten that I had middleware in place where if the user was not authenticated when performing the search they were redirected to the login page. So I was getting a bunch of html returned for this login page, rather then my json. What still confuses me is why my breakpoints in search function were ever hit if I was being redirected before ever reaching this function.

AngularJS $http post to non existing url 404

This may be one of these questions that doesn't need much explanation i just didn't found the answer elsewhere.
I'm pretty new to AngularJS and NodeJS. I did some tutorials and now i try to put something together.
In nodeJS when i do something like this:
app.get('/db-get-extra-bookings', function(req, res) {
res.json({name: "hello"});
});
than in AngularJS i can GET that response and do something with that even if /db-insert-extra-bookings is not an fysical page
return $http
.get(formURL)
.then(function(response){
// some code
});
But when i want to post something from out of AngularJS to my NodeJs environment
return $http
.post(formJson, JSON.stringify(bookings))
.then(function(response){
//some code
});
NodeJS:
app.get('/db-insert-extra-bookings', function(req, res) {
// do something with the request
});
I got a 404 error in my webbrowser console.
base.js:5 POST http://localhost:3000/db-insert-extra-bookings 404 (Not Found)
It sounds like normal behaviour, but why am i getting a 404 error when i POST to a non existing page, and why am i getting the data like i want when i GET from a non existing page?
Do i really need to make an empty page to post to?
I'm not a expert in NodeJS, but if you want to create a route that answer any HTTP method you should use app.all() instead of app.get(). In your code you are just creating a route for GET requests, that is why it works for a GET and don't work for a POST. Check out this reference
Just to clarify, NodeJS endpoints (GET included) do not need to serve an HTML page to work. You can send any type of HTTP response, e.g. plain text, JSON, HTML, etc - with the appropriate 'Content-Type' header.
In NodeJS routes:
app.post('/db-get-extra-bookings', function(req, res) {
res.json({name: "hello"});
});
Now in your angular code (You don't need to JSON.stringify):
// Change localhost:9000 with your hostname
$http.post('http://localhost:9000/db-get-extra-bookings', bookings)
.success(function (data, status, headers, config) {
// console.log(data);
})
.error(function (data, status, headers, config) {
// console.log(status);
});
Also, remember to restart your NodeJS server for the changes to take effect.

Resources