I have a login system in my website and I want to show the name of the user in the frontend using AngularJS, but I don't know how to pass the user from NodeJS
app.get('/main', isLoggedIn, function(req, res){
res.render('main.ejs', {
user : req.user
});
});
From the looks of the snippet you provided.
Your incoming data is already the user you wish to display.
In ExpressJS:
req stands for the Request, coming in from the Client.
res stands for the Response, going back to the Client.
Good article on ExpressJS Here, it goes a bit more in-depth.
If your goal is to contact the DB when you receive a username and password from the client, then display back the user's full name. Then do something like this.
Client (AngularJS)
app.service('SomeService', ['$http', function ($http, ) {
this.loginUser = function(user, pass) {
var model = {
user: user,
pass: pass
};
var promise = $http.post('/Account/Login', JSON.stringify(model))
.then(function(response) {
return {
response.fullName
};
}, function() {
//Error
};
});
return promise;
};
}]);
On your Server
app.get('/Account/Login', function(req, res) {
//Do Logic magic here....
return res.json({ fullName: 'John Doe'});
});
Finally your Controller and HTML
After doing the round trip, your JS Promise will be returned to the original caller of the Angular Service and you can populate a $scope variable then display it however you wish. Take a look:
app.controller("MyController", function('SomeService'){
$scope.fullName = '';
SomeService.loginUser ('userCool','password123')
.then(function (response) {
$scope.fullName = response.fullName;
}, function () {
//Some Error, Server did not respond...
});
});
HTML
<div ng-controller="MyController">
<label ng-bind="fullName"></label>
</div>
First, set it up on server side:
app.get('/api/:paramID1/:paramID2', function(req, res) {
return res.json({ user: 'example' });
});
On the client side you need an ajax call to invoke the service like:
$http.get( "/api/1/abc").success(function(data) {
$scope.user = data;
});
Related
Introduction
OK, what I have is a app built in Node and Angular. I pass A users email to my backed using a post in Angular, from the backed the order in the backed is:
Get the email
Get API key
Post email and API key to API
I do this by posting email to backed then using node and express get email use promise resolve (first function) to pass the email to my third function as well as the API key retrieved from the second function.
What I need
Angular post to back end Node
Run first function, If first function has retrieved the email then run function 2. if not correct then pass information to the first post (Angular) to display message.
Run second function, if true run function 3
Finally run post with data collected from function 1 and 2, if post correctly pass 200 code to first function or pass to angular post.
Needed
Verification on the front end (Angular) on each step (function 1, 2 and 3 in Node) they can be response code so that I may print a different message depending on response code
Objective
A user post email on front end, then depending on if the email was accepted on the API let the user know, This is where different messages or redirects come in to play depending if it was a wrong or right email.
My Code
Angular side
This is where the first post to the Node back end happens, would be nice if this could get different response request depending on the results on the back-end.
var firstFunction = function () {
return new Promise(function (resolve) {
setTimeout(function () {
app.post('/back-end/controller', function (req, res) {
console.log(req.body);
var login = req.body.LoginEmail;
res.send(login);
resolve({
data_login_email: login
});
});
console.error("First done");
}, 2000);
});
};
Node side (all in controler.js)
First function
I would like this to trigger function 2 if success if not send a response code back to the Angular request.
var firstFunction = function () {
return new Promise(function (resolve) {
setTimeout(function () {
app.post('/back-end/controller', function (req, res) {
console.log(req.body);
var login = req.body.LoginEmail;
//Promise.all([firstFunction(), secondFunction()]) .then(thirdFunction);
//res.send(login);
resolve({
data_login_email: login
});
});
console.error("First done");
}, 2000);
});
};
Second function
This function gets API key, if This function is successful trigger function three.
var secondFunction = function () {
return new Promise(function (resolve) {
setTimeout(function () {
nodePardot.PardotAPI({
userKey: userkey,
email: emailAdmin,
password: password,
DEBUG: false
}, function (err, client) {
if (err) {
// Authentication failed
console.error("Authentication Failed", err);
} else {
// Authentication successful
var api_key = client.apiKey;
console.log("Authentication successful !", api_key);
resolve({data_api: api_key});
}
});
console.error("Second done");
}, 2000);
});
};
Third Function
If second function passes then this function should run using the email from the first and the API key from the second, If success then pass pass success back to first function to pass give 200 success to the angular side, or directly send a request response to Angular, If fail then again let the front end know.
function thirdFunction(result) {
return new Promise(function () {
setTimeout(function () {
var headers = {
'User-Agent': 'Super Agent/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded'
};
// Configure the request
var api = result[1].data_api;
var login_email = result[0].data_login_email;
var options = {
url: 'https://pi.pardot.com/api/prospect/version/4/do/read',
method: 'POST',
headers: headers,
form: {
'email': login_email,
'user_key': userkey,
'api_key': api
},
json: true // Automatically stringifies the body to JSON
};
// Start the request
rp(options)
.then(function (parsedBody) {
console.info(login_email, "Is a user, login pass!");
// router.redirect('/login'); // main page url
// res.send.status(200);
})
.catch(function (err) {
console.error("fail no such user");
// res.status(400).send()
});
console.error("Third done");
}, 3000);
}
);
}
Promise.all([firstFunction(), secondFunction()]) .then(thirdFunction);
If anyone knows how to do this please can you help, this is the last part of my app i need to get working, Thanks.
Summery
In summery I would like different response codes Angular side depending on where and when the function got to on backed or if it passed all three functions.
Eg:
request code for fails to post to backed
Fails to get API key on function 2
Fails to send email to API on third function
Email not present on API
Email present on API and all pass, Your In !!
UPDATE
I found I can pass a message back to my Angular post using the following, but how can I make this message different depending on what function has run ?
var firstFunction = function () {
return new Promise(function (resolve) {
setTimeout(function () {
app.post('/back-end/controller', function (req, res) {
console.log(req.body);
// res.status(500).send({ error: "boo:(" });
res.send('hello world');
var login = req.body.LoginEmail;
res.send(login);
resolve({
data_login_email: login
});
});
console.error("First done");
}, 2000);
});
};
I solved this by merging 2 function into one (the retrieve function and post) then i changed the promise chain
var firstFunction = function () {
return new Promise(function (resolve) {
setTimeout(function () {
nodePardot.PardotAPI({
userKey: userkey,
email: emailAdmin,
password: password,
DEBUG: false
}, function (err, client) {
if (err) {
// Authentication failed
console.error("Authentication Failed", err);
} else {
// Authentication successful
var api_key = client.apiKey;
console.log("Success your API key is", api_key);
resolve({data_api: api_key});
}
});
}, 2000);
});
};
var secondFunction = function (result) {
return new Promise(function () {
setTimeout(function () {
app.post('/back-end/controller', function (req, res) {
console.log(req.body);
var login = req.body.LoginEmail;
var api = result[0].data_api;
var headers = {
'User-Agent': 'Super Agent/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded'
};
var options = {
url: 'https://pi.pardot.com/api/prospect/version/4/do/read',
method: 'POST',
headers: headers,
form: {
'email': login,
'user_key': userkey,
'api_key': api
},
json: true // Automatically stringifies the body to JSON
};
if (login.length !== 0) { // maybe use node email validation ?
console.log("Email Accepted, Next posting to API.......");
rp(options)
.then(function (parsedBody) {
console.info(login, "Is a user, login pass!");
res.status(200).send({ user: login });
})
.catch(function (err) {
console.error("fail no such user");
res.status(400).send('fail to login');
});
} else {
console.log("Failed to get email from front end");
res.status(404).send('Incorrect length');
}
});
});
});
};
Promise.all([firstFunction()]).then(secondFunction);
I am trying to make GET request with node request module. I am making request to the coursera api. As the api is using CORS. Therefore I have to make server side requests.
But the thing is how to use this data in index.html to dynamically fill data.
As here I am getting the whole data to the file. Is there any way to give this data to the Angular controller.
In brief, I want to use data from coursera api inside my angular app. I have used client side so know less about server side.
var request = require("request");
var fs = require("fs");
request("https://api.coursera.org/api/courses.v1").pipe(fs.createWriteStream("data.json"));
There are two ways you can get the data into index.html:
1) Use Jade (Pug) Render:
var COURSERA_DATA = null;
router.get('/', function (req, res) {
if (!COURSERA_DATA) {
request("https://api.coursera.org/api/courses.v1",function(err,res,body) {
COURSERA_DATA = body; /* verify first */
res.render('index', {data: COURSERA_DATA});
});
} else {
res.render('index', {data: COURSERA_DATA});
}
});
and then in index.html:
script(text/javascript).
var theDATA = !{JSON.stringify(data)}; // inserted by jade
and finally in angular1
app.controller('AnyController',function() {
var vm = this;
vm.data = theDATA;
});
2) Client request to URL which is proxied to coursera's API
router.get('/coursera', function (req, res) {
request("https://api.coursera.org/api/courses.v1").pipe(res);
}
Aaron
Why the problem to consume data right in Angular? Something like:
app.controller('controller', function($scope, $http) {
$scope.getCursera = function() {
$http({
url: "https://api.coursera.org/api/courses.v1",
method: "GET",
contentType: "application/json"
}).success(function(data) {
$scope.jsonResponse = data;
}).error(function(err) {
console.log(err);
});
};
});
If Coursera allow Cross Domain this it's works. The JSON response will be setted at the scope, such that you be able to show in view or do anything.
You can try to implement a simple api to send the response back to your controller like this..
In the server side .. (Demo)
var request = require('request');
router.get('/coursera', function (req, res,next) {
request.get(
'https://api.coursera.org/api/courses.v1',
{ json: { key: 'value' } },
function (error, response, body) {
if (!error && response.statusCode == 200) {
res.send(body); //response from coursera
// if you are using this as middleware write next()
}else {
res.send(new Error("Error while connecting to coursera"));
// if you are using this as middleware write next(err)
}
);
}
And in the angular controller ..
app.controller('controller', function($scope, $http) {
$scope.getCoursera = function() {
$http({
url: "baseURL/coursera",
method: "GET",
}).success(function(data) {
$scope.data = data;
}).error(function(err) {
console.log(err);
});
};
});
I'm trying to create an authentication-service in angular in order to register/login users.
After registering a new user I have some trouble receiving the response to the service.
Here is the flow:
Front-end controller that passes the new user to the Auth-service:
vm.onSubmit = function () {
Authentication
.register(vm.credentials)
.then(function(){
$location.path('/');
});
};
The Authentication-services register-function
register: function(user) {
return $http.post('/api/register', user).success(function(data){
console.log('authserviceDONE'); //I never get back here...
});
},
The api/register -route
app.post('/api/register', function(req, res) {
User.register(new User({ username: req.body.username}), req.body.password, function(err,user) {
if (err) {
return res.json(err);
}
passport.authenticate('local')(req, res, function () {
console.log(req.user); // User gets logged
return req.user;
});
});
});
I am hoping to receive the user-object in the front-end in order to log him in to the app but the Auth-service never receives anything. Any tips on what I might be missing here?
I do not know how your project is structured so I am going to show you what works for me. I usually have three files: app.js controllers.js services.js - this is pretty standard.
Here is an example:
app.js
angular.module('myApp', ['myApp.controllers', 'myApp.services'])
.config(function (...) { ...
controllers.js
angular.module('myApp.controllers', [])
.controller('myCtrl',function($scope, srvAccount, $log){
srvAccount.getaccount()
.then(
function(response){
$scope.account = response.data;
$log.info(response.data);
},
function(rejection){
$log.error("getaccount error");
$log.log(rejection);
}
);
...
and finally services.js
angular.module('myApp.services', [])
.factory('srvAccount', function ($http) {
return {
getaccount: function () {
return $http({
method: 'GET',
url: 'api/getaccount'
});
}
}
});
Have the browser developer tools > console open and use AngularJS $log to debug. More on $log here https://docs.angularjs.org/api/ng/service/$log
Here i need to search name in scroll,for that i send search data query string in get call but i need to that in post.
Here is my server and client controller route and service.Also here i handling search from server side.How to post data which user has been searched ,and pass that to client and server side.
client controller service:
'use strict';
angular.module('details').factory('DetailService', ['$resource',
function($resource) {
return $resource('details', {
},
searchUsers:{
method: 'GET',
}
});
}
]);
Angular controller:
$scope.searchServer = function(searchData){
DetailService.searchUsers({search:searchData},function(response){
}, function(error){
$scope.status = 'Unable to load customer data: ' + error.message;
});
}
my Server side controller:
exports.searchCust = function (req, res) {
var strWhere = {
corporateName: search
};
db.Customer.findAll({
where: [strWhere],
}).then(function (customers) {
if (!customers) {
return res.status(400).send({
message: 'Customer not found.'
});
} else {
res.jsonp(customers);
}
})
};
my server sideroute:
app.route('/details').all(customersPolicy.isAllowed)
.get(details.searchCust);
app.param('search', details.searchCust);
};
I didn't try it out in all details as it looks like it was copy and pasted together without reading the basics. However, if you want POST requests, you need to set them both in the node-code and the Angular code, see below. What's more, Angular doesn't use JSONP, it uses JSON, so you need to set that. In the searchUsers-resource-call you only implemented the error-branch, so the results would just vanish. You'll find them in $scope.searchResults now.
client controller service:
'use strict';
angular.module('details').factory('DetailService', ['$resource',
function($resource) {
return $resource('details', {},
searchUsers: {
method: 'POST',
}
});
}]);
Angular controller:
$scope.searchServer = function(searchData) {
DetailService.searchUsers({
search: searchData
}, function(response) {
$scope.status = "OK";
$scope.searchResults = response;
}, function(error) {
$scope.status = 'Unable to load customer data: ' + error.message;
});
}
my Server side controller
exports.searchCust = function(req, res) {
var strWhere = {
corporateName: search
};
db.Customer.findAll({
where: [strWhere],
}).then(function(customers) {
if (!customers) {
return res.status(400).send({
message: 'Customer not found.'
});
} else {
res.json(customers);
}
})
};
my server sideroute:
app.route('/details').all(customersPolicy.isAllowed)
.post(details.searchCust);
app.param('search', details.searchCust);
};
I have the following:
Node/Express router:
var City = require('./models/city');
module.exports = function(app) {
app.get('/cities/:zip', function(req, res) {
console.log(req.params.zip);
var query = City.find({"zip" : req.params.zip})
query.exec(function(err, city) {
if (err)
res.send(err);
console.log(city);
res.json(city);
});
});
app.get('*', function(req, res) {
res.sendfile('./public/views/index.html'); // load our public/index.html file
});
};
Angular Service:
angular.module('CityService', []).factory('City', ['$http', function($http) {
return {
get : function(zip) {
var zip = zip.zip
return $http.get('/cities/' + zip);
}
}
}]);
Angular Controller:
angular.module('CityCtrl', []).controller('CityController', ['$scope', '$http', 'City', function($scope, $http, City){
$scope.update = function (zip) {
$scope.weather = City.get({zip : zip});
if(zip.length = 5){
$http.jsonp('http://api.openweathermap.org/data/2.5/weather?zip='+ zip +',us&callback=JSON_CALLBACK').success(function(data){
$scope.data=data;
console.log(data.name);
});
}
}
}]);
Everything seems to be working fine. However, when I try to log the $scope.weather I get the entire header. I've tried logging $scope.weather.name (I know it's there) and then it returns "undefined". When I check what the server is logging it appears to log the correct JSON response. Any idea of how to get the "name" field of the returned document?
Replace $scope.weather = City.get({zip : zip}); to City.get({zip : zip}).then(function(response){$scope.weather= response.data});
As we know $http return a promise object so you must have to resolve it. you are not resolving it in service so you have to set $scope.weather in then.