How to retrieve data from api res.send? - javascript

I am using the javascript MEAN stack for my single page app.
I have an Angular factory making a call to my Api.
app.factory('authorizing', function($resource){
return $resource(
'/api/authorizing/:username',
{'username':'#username'},
// retreiving only one user and all their roles
{'singleUser' : {
method:'GET'
,isArray: false
}}
);
});
I call the factory in my controller like this. My goal is to update the web page data based on the response I get back from the Api. I expect a true or false value to be returned. I have tried other things but I want to keep my authorization on the server side.
app.controller('usrPageController', function ($scope, usrServiceById, $route, authorizing, $rootScope) {
$scope.updateUser = function (data,field){
var vCheckUserRoles;
vCheckUserRoles = authorizing.singleUser({'username': $rootScope.current_user});
if (vCheckUserRoles == true){
usrServiceById.update({'username':username},{field:data, 'fieldName':field});
};
};
});
The database returns the result data using a res.send.
.get(function (req, res) {
RoleUser.find({ 'aclUserName': req.params.username }, function (err, aclUser) {
if (err) { return res.sendStatus(500) };
// return an error if no user is found
if (aclUser == null) { return res.sendStatus(401) };
//check for proper role in list of users
for (var i = 0; i < aclUser.length; i++) {
if (aclUser[i].aclUserResource == req.params.username + '_PROFILE') {
//return a successful status
return res.send('true');
};
};
//return a failed status
return res.send('false');
});
});
I don't get any errors from the code but the return object is empty when it hits the controller after the res.send. I have tried different types of data to return but nothing seems to work for me. Any help is appreciated. I have othe res.send calls in my Api. They work but I take the data directly from my database wiht the callback and feed it to the res.send. This is the only time in my code that I am trying to return something besides the successful callback variable.
UPDATED CODE:
I removed the var vCheckUserRoles. Now the value is passed to a success callback
app.controller('usrPageController', function ($scope, usrServiceById, $route, authorizing, $rootScope) {
authorizing.singleUser({'username': $rootScope.current_user},function(response){
console.log('response = ' + response.data)
if (response.data == 'true'){
usrServiceById.update({'username':usrSingle.username},{field:data, 'fieldName':field});
};
});
});

You can use res.json instead of res.send to send status of your query.
Example ////
res.json({status:true})
And on client side you can access that status value in data.status field.

On the server you send data as follows:
res.status(200).send({message: "Hello!"});
In the front-end you receive the data, then resolve it to get data as follows:
fetch(url)
.then(response => {
if(response.ok) {
return response.json();
}
}).then(data => {
if(data) {
console.log(data);
}
}).catch(err => console.error(err));

Related

Differentiate between redirect/JSON-data in response from fetch API request

i am trying to build a logic at front end to differentiate between the redirect and JSON response, the end goal for this is as, if the response is redirect go to that page and if the response is having data then it will render that data on the page.
Note: it is working fine if the back end send response as either res.redirect or res.json, but i am struggling (as in below code) as when i have to check first as what the response is from back end , i thought as if i can use if else statement at front end to disgusting between res.json and res.respond, i have tried like .then(res.redirect=>{…}).then(res.json=>{}) but it doesn’t look like if i am using the correct logic.
Any suggestions please, thanks :slightly_smiling_face:
Snippet from my front end code is .
const request = new Request("http://localhost:5000/api/newuser", options);
(async () => {
const incomingdata = await fetch(request)
*// below i differetiated the incoming response as if it is res.redirect or res.json data but didnt work*
.then((res.redirect) => {
window.location.href = res.url;
})
.then((res.json) => {
console.log("cannot find data");
})
.catch((err) => console.log("err"));
Snippet from my bank end code is,
connection.query("SELECT * FROM users WHERE email=?;", [x1.Email], function (
err,
results
) {
console.log("74",results, err);
console.log("75",results[0].email);
if (err) throw err;
else {
if (results[0].email && results[0].password) {
console.log("79",results[0].email);
//console.log(results[0]);
if (results[0].password == x1.password)
res.redirect("http://localhost:3000/");
else {
res.json({
data: "invalid password",
});
}
} else res.redirect("http://localhost:3000/about");
}
});
});
For redirect you can check if the HTTP code is in the 300 range, which is provided in res.status. It won't take dot notation, So, you can use
.then(res => {
if(res.status >= 300 && res.status < 400){
// redirect
} else {
return res.json();
}
})
.then(data => {
//handle your json data
});
It would be a syntax error to use a dot in the callback argument like:
.then((res.json) => {
However, it would be possible to deconstruct an object like this:
.then(({ status, json }) => {

How to access DB from a function and only then send a post request?

I need help to integrate a few actions inside a function.
I get a call from PayPal, then i need to :
Access my DB to compare.
If ok send 200 OK
Send the request body back.
Currently - I do (3) only, and it somehow works without (2).
exports.contentServer = functions.https.onRequest((request, response) => {
....
....
if(request.path === paid)
{
if (request.method !== "POST")
response.status(405).send("Method Not Allowed");
else {
let ipnTransactionMessage = request.body;
let formUrlEncodedBody = querystring.stringify(ipnTransactionMessage);
let verificationBody = `cmd=_notify-validate&${formUrlEncodedBody}`;
//______________
//** at this point i need to read a firebase collection and return 200OK , ONLY THEN DO THE POST BELOW
var docRef = admin.firestore().collection('All').doc(ipnTransactionMessage.custom);
docRef.once('value').then(function(snapshot) {
console("our data to compare",snapshot);
res.status(200); // ?
});
//**** how do i do the next only after the previous ?
let options = {
method: 'POST',
uri: "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr",
body: verificationBody
};
return rp(options)
.then(body => {
if (body === "VERIFIED") {
//** we are done here - and this actually works already
})
.then(docReference => {
console.log("Request completed");
return response.send({ result: 'ok' });
})
.catch(error => {
console.log(error);
return response.status(500).send(error);
});
See the comment in the code. After reading my DB and respond with 200 OK , only then i would like to send back the body as I do.
As Doug mentioned the code needs to go in the then clause:
I took a part of your code to shaow where the code to get executed only when firestore answers can go.
//** at this point i need to read a firebase collection and return 200OK , ONLY THEN DO THE POST BELOW
var docRef = admin.firestore().collection('All').doc(ipnTransactionMessage.custom);
docRef.once('value').then(function(snapshot) {
console("our data to compare",snapshot);
res.status(200); //
if(snapshot.exists){
// ---------------------------------
// The code that you want to get executed only
// firestore answers Goes Here
// ---------------------------------
}
});

How to reuse fetched data from API?

I'm fetching data from a API that returns a JSON object:
fetch("api.php")
.then(function(response) {
console.log("Status: " + response.status);
if (response.ok) {
return response.json();
} else {
throw Error(response.status);
}
}).then(function(json) {
json.forEach(function(item) {
// 'datas' contains the items extracted from the JSON response
datas.add(item);
});
}).catch(function(err) {
console.log(error);
});
If I want to query the data with jinqJs I can change the code slightly to:
}).then(function(json) {
var result = new jinqJs()
.from(json)
.where('start_date = 2017-03-10')
.select();
result.forEach(function(item) {
datas.add(item);
});
}).catch(function(err) {
and it works really well.
My question is: due to the fact that by fetching only once the API I actually download ALL the needed data how can I query it 'outside' the forEach fetch?. I mean: I already have all the data with one call to the API, I can easily do queries on the data with jinqJs why should I call the API every time I need to query it? Is it possible to query datas once the forEach has added all the items?
For example, outside the forEach (notice the .from(datas) instead of .from(json)) I could do:
var result = new jinqJs()
.from(datas)
.where('start_date = 2017-03-10')
.select();
and get the same result.
As I'm trying to build a mobile app, this would be handy because I would bind the above code to specific buttons and query the data accordingly and I would connect to the internet only the first time the app is started rather than every time a query is needed.
Assign the "JSON" promise to a variable
var something = fetch("api.php")
.then(function(response) {
console.log("Status: " + response.status);
if (response.ok) {
return response.json();
} else {
throw Error(response.status);
}
});
Now you can use something as many times as you like
something
.then(json => console.log(json))
.catch ...
something.then(json => new jinqJs()
.from(json)
.where('start_date = 2017-03-10')
.select()
.forEach(function(item) {
datas.add(item);
});
).catch ....

how show response data in other page angularjs

Using the code snippet below I'm authenticating email, password. The customerlogin() method returns some JSON data which I want to show in the next page. In other words I want to pass the data returned from customerlogin() to then() and then pass it to /customerprofile
Please help
login(form) {
this.submitted = true;
if (form.$valid) {
this.Auth.customerlogin({
email: this.operator.email,
password: this.operator.password
})
.then(() => {
// Logged in, redirect to home
this.$location.path('/customerprofile');
})
.catch(err => {
this.errors.login = err.message;
});
}
}
//Other file Auth.js
customerlogin({
email,
password
}, callback) {
console.log('Customer Authentice Method');
return $http.post(properties.customer_login, {
email, password
})
.then(res => {
properties.GetId = res.data.id;
$cookies.put('token', res.data.token);
currentUser = User.get();
return currentUser.$promise;
})
.then(user => {
safeCb(callback)(null, user);
return user;
})
.catch(err => {
Auth.logout();
safeCb(callback)(err.data);
return $q.reject(err.data);
});
}
i want show data these textbox
enter image description here
Your login function should be calling a service method which makes the ajax call and stores the response as an object property on that service. The controller then has that on scope because you've injected the service. There's nothing to pass. It's already there and is watched automatically by Angular.
Something like this:
angular.someModule('someModule')
.service('someService', function($http) {
return {
loginCall: function(...) {
// do ajax call here
return loginStuff; // must be an object (or wrapped in one)
}
};
})
.controller('SomeController', ['someService', function(someService) {
var sc = this; // controllerAs syntax
sc.login = function(form) {
someService.customerlogin(...).then(...).catch(...);
// because someService has been injected, someService.loginCall is now
// available and being watched by the controller, on its scope...
// and can be used in your view like {{someService.loginCall.dataProperty}}
...
};
}]);
There are probably some missing pieces here (module injections), but this should get you started.
At first, try to use this construction for your .then:
.then(function (data) {
$log.debug(data); //to console log passed data via angular
});

MEAN.io Strange $http.get Response

I am trying to develop a user management feature for a website using the MEAN.io stack. What I'm trying to do has worked in the past for other models on the same site so I'm not sure what is going on. My issue is that I am trying to get all the User models from the MongoDB database and pass them to an AngularJS controller so that I can display their information on a user management page. To that end, I added this function to the User controller in the backend:
exports.readUsers = function(req, res) {
var decodedToken = req.decodeToken;
var User = mongoose.model('User');
var id = req.params.id;
existUser(decodedToken, function(err, user) {
if(err) {
return sendError(res, 'INVALID_TOKEN');
}
User.find({})
.select('username')
.exec(function(err, results) {
if(err) {
return sendError(res, err);
}
res.json({success: true, userList: results});
});
});
}
This line to the routing code:
router.get('/users/all', Authorization.token, user.readUsers);
And this AngularJS controller for use with the frontend:
(function () {
"use strict";
var app = angular.module("GAP");
app.factory("UserEditFactory", function UserEditFactory($http, API_URL, AuthTokenFactory, $q) {
"use strict";
return {
readUsers: readUsers
};
//Get all users in the DB
function readUsers() {
if(AuthTokenFactory.getToken()) {
return $http.get(API_URL + "/users/all");
}else {
return $q.reject({
data: "valid token required"
});
}
}
});
app.controller("userPageController", ["UserEditFactory", "$scope", "$http", "$window", "API_URL",
function(UserEditFactory, $scope, $http, $window, API_URL) {
UserEditFactory.readUsers().then(function(data) {
console.log(data.data);
$scope.users = data.data.userList;
}, function(response) {
console.log(response);
});
}
]);
})();
When I load the page that is supposed to display this information, no data is displayed. I have determined that the AngularJS controller is calling the second function which I understand is the one used to respond to an error.
Further investigation of the object returned by the $http.get call reveals no data, and a status of -1. I'm not sure why this is happening, because I have used this exact pattern of code to get and display data from other models in the database on the same site. I can manually make HTTP calls to those working functions from this controller, and everything works fine. I'm not sure where to go from here or how to learn more about the issue. Can anyone offer insight? Let me know if you need more information.
Edit: As requested, here is the code for the AuthTokenFactory, which is an app.factory object in a common JS file.
app.factory('AuthTokenFactory', function AuthTokenFactory($window) {
'use strict';
var store = $window.localStorage;
var tokenKey = 'auth-token';
var userKey = "username";
return {
getToken: getToken,
setToken: setToken,
setUsername: setUsername
};
function getToken() {
return store.getItem(tokenKey);
}
function setToken(token) {
if (token) {
store.setItem(tokenKey, token);
} else {
store.removeItem(tokenKey);
}
}
function setUsername(username) {
if (username) {
store.setItem(userKey, username);
} else {
store.removeItem(userKey);
}
}
});

Categories

Resources