Angular communication with back-end - angularjs

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

Related

Passing object from Node/Express Router to AngularJS Controller

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.

handle asynchronous behavior firebase in angularjs

I'm trying put the authentication of my firebase in a service. But I stumbled on some problems with program flow. The response from firebase is slower and the code needs to wait for it to complete.
I tried to create a promise, but it doesnt work properly.
Here is my code:
//controller.js
articleControllers.controller('AuthController',
['$scope', '$firebaseObject', 'AuthenticationService',
function($scope, $firebaseObject, AuthenticationService){
$scope.login = function() {
AuthenticationService.login($scope.loginForm)
.then(function(result) {
if(result.error) {
$scope.message= result.error.message;
}
else {
console.log("user");
}
});
};
}
]);
services.js
myApp.factory('AuthenticationService',
function($firebase, $firebaseAuth, $routeParams, FIREBASE_URL) {
var auth = new Firebase(FIREBASE_URL);
var myReturnObject = {
//user login
login: function(user) {
return auth.authWithPassword({
email: user.loginEmail,
password: user.loginPassword
},
function(error, authData) {
console.log("hit after .then");
return {
error: error,
authData: authData
}
});
}
};
return myReturnObject;
});
I already used a promise once in my code for a $http get request. But for firebase it doesnt seem to work. I get the error: Cannot read property 'then' of undefined in controller.js.
Anyone an idea how I can let angular wait for the service?
remember to inject $q.
myApp.factory('AuthenticationService',
function($q, $firebase, $firebaseAuth, $routeParams, FIREBASE_URL) {
var auth = new Firebase(FIREBASE_URL);
var myReturnObject = {
//user login
login: function(user) {
return $q(function(resolve, reject) {
auth.authWithPassword({
email: user.loginEmail,
password: user.loginPassword
}, function authCallback(error, authData) {
if (error) {
return reject(error);
}
resolve(authData);
});
});
}
};
return myReturnObject;
});

Show username from Nodejs

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;
});

angular phonegap - my factory not delivering data

I am trying to create a Phonegap App. I use Angular as frontend.
I have a factory that gets data from an external ressource. In .config i added the access origin * attribute.
When I debug using http://debug.build.phonegap.com it seem to returning the data. The call to the API is returning 584 bytes.
So there seems to be an issue regaring the data from the factory to the frontend.
My Factory
.factory('ActivityService', ['$http', '$location', 'CookieService', function ($http, $location, CookieService) {
return {
getActivitiesService: function (data) {
$http.post('http://www.example.com/api/v1/Activity.php',
{
MethodName: "getActivitiesService",
SessionToken: CookieService.getCookie("ua_session_token")
})
.success(data)
},
postActivityService: function (activity) {
$http.post('http://www.example.com/api/v1/Activity.php',
{
MethodName: "postActivityService",
SessionToken: CookieService.getCookie("ua_session_token"),
ActivityName: activity.activityName,
ActivityDescription: activity.activityDescription
}).success(function () {
$location.path("/home");
});
}
}
}])
My controller
.controller('HomeCtrl', ['$scope', 'ActivityService', function($scope, ActivityService) {
//GET activities from server / DB
ActivityService.getActivitiesService(function (data) {
if (jQuery.isEmptyObject(data))
{
$scope.emptyJsonArray = "No activities.";
}
else
{
$scope.$apply(function () { $scope.activities = data; });
}
})
}])
In my app.js i do this:
//Manually bootstrapping Angular, after cordova.
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
angular.element(document).ready(function () {
angular.bootstrap(document, ['attenttoApp']);
});
};
Update:
Thanks both of you. I checked the content of the returned data, and it was an error that was returned.
Fixed it and now i works...
in the doc, they use return in factory
https://docs.angularjs.org/api/ng/service/$http
so try it like this
getActivitiesService: function (data) {
var toreturn = $http.post('http://www.example.com/api/v1/Activity.php',
{
MethodName: "getActivitiesService",
SessionToken: CookieService.getCookie("ua_session_token")
})
.success(function(data, status, headers, config) {
return data;
})
return toreturn;
},
and i think you should see in direction of promises, i wrote an answer about this, look at it
For which status codes promise resolving

Why promise doesnt work as expected in AngularJS

In my AngularJS application on every request to change the page i run :
$rootScope.$on('$locationChangeStart', function (event, next, current) {
var user;
$http.get('/api/Authentication/UserAuthenticated').then(function (data) {
console.log("call");
user = data.data;
});
console.log("end of call");
});
When i run application and test what is happening i see in console that "end of call" is returned before console.log("call"); which means that user is not set. Which means that if i want to check if user is logged in on change of route user will be undefined.
How do i make Angular run-> http request and only then keep going?
I misunderstood the question a bit. You can let the $routeProvider resolve the $http promise:
var app = angular.module("myApp");
app.config(["$routeProvider", function($routeProvider) {
$routeProvider.when("/",{
templateUrl: "myTemplate.html",
controller: "MyCtrl",
resolve: {
user: ["$http", "$q", function($http, $q) {
var deferred = $q.defer();
$http.get('/api/Authentication/UserAuthenticated').success(function(data){
deferred.resolve(data.data);
}).error(function(error) {
deferred.resolve(false);
});
return deferred.promise;
}]
}
});
}]);
If the code to fetch the user data is too complex, you could create a service for it, and inject that service in the $routeProvider's resolve function.
In your controller, you just inject the promise (which will be resolved):
app.controller("MyCtrl",["$scope","user", function($scope, user) {
if (!user) {
alert("User not found");
}
...
}]);
use async:false. It is working for me
Try this code, instead of your code
$rootScope.$on('$locationChangeStart', function (event, next, current) {
$http({method: 'GET',
url: '/api/Authentication/UserAuthenticated',
async: false
}).success(function (data) {
console.log("call");
user = data.data;
}
console.log("end of call");
});

Resources