$scope value does not udate - Angularfire - angularjs

I'm having a problem with my code. $scope value is not updating after $createUserWithEmailAndPassword. but if i do alert($scope.message), I can see the alert. Where am i going wrong?
I'm using all the updated files from firebase and Angularfire.
My app.js
`
var spaapp = angular.module('spaapp', ['ngRoute', 'firebase']);
spaapp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/login', {
templateUrl: 'login.html',
controller: 'spaController'
}).
when('/register', {
templateUrl: 'register.html',
controller: 'spaController'
}).
when('/success', {
templateUrl: 'success.html',
controller: 'spaController'
}).
otherwise({
redirectTo: '/Main'
});
}]);
'
My Controller
spaapp.factory("Auth", ["$firebaseAuth",
function($firebaseAuth) {
return $firebaseAuth();
}
]);
spaapp.controller('spaController', ['$scope','$rootScope', 'Auth',function ($scope,$rootScope,Auth) {
// $scope.authObj=firebaseAuth();
//var auth = Auth;
$scope.login = function () {
}
$scope.register = function () {
var email = $scope.user.email;
var password = $scope.user.password;
Auth.$createUserWithEmailAndPassword(email, password).then(function(regUser){
$scope.message="Hi" + regUser.uid;
console.log("Signed in as:" + regUser.uid );
}).catch(
function(error) {
var errorCode = error.code;
var errorMessage = error.message;
console.log(error.message);
$scope.message = error.message;
});
};
}]);
Any help is appreciated.
Thanks

You can refresh angular's $scope by calling $apply() on $scope
Example:
spaapp.factory("Auth", ["$firebaseAuth",
function($firebaseAuth) {
return $firebaseAuth();
}
]);
spaapp.controller('spaController', ['$scope','$rootScope', 'Auth',function ($scope,$rootScope,Auth) {
// $scope.authObj=firebaseAuth();
//var auth = Auth;
$scope.login = function () {
}
$scope.register = function () {
var email = $scope.user.email;
var password = $scope.user.password;
Auth.$createUserWithEmailAndPassword(email, password).then(function(regUser){
$scope.message="Hi" + regUser.uid;
console.log("Signed in as:" + regUser.uid );
}).catch(
function(error) {
var errorCode = error.code;
var errorMessage = error.message;
console.log(error.message);
$scope.message = error.message;
$scope.$apply() // HERE
});
};
}]);
More about angular's digest loop at:
http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

Related

AngularJS - access factory service from the controller

I'm trying to access factory service within controller to obtain correct data.
Related controller code looks like:
myApp.controller('RegistrationController', ['$scope','$routeParams','$rootScope','$location','$filter','$mdDialog','checkAttendee', function($scope, $routeParams, $rootScope, $location, $filter, $mdDialog,checkAttendee){
...
$scope.addAttendee = function(ev) {
$mdDialog.show({
controller: AddDialogCntrl,
templateUrl: 'views/regForm.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true,
controllerAs: 'ctrl',
fullscreen: $scope.customFullscreen, // Only for -xs, -sm breakpoints.
locals: {parent: $scope}
})
.then(
function(response){
if(angular.isDefined(response)){
attendees.push(response);
checkAttendee.getAttendeeInfo(response);
}
},
function(){
//no changes
}
)
.catch(
function(error) {
console.log('Error: ' + error);
}
)
};
and factory service code
myApp.factory('checkAttendee', ['$http', function($http) {
this.getAttendeeInfo = function(req) {
return $http.get("/check/attendee/", {params:{"firstName":req.firstName, "lastName":req.lastName, "email": req.email, "eventID": req.eventID}})
.then(function(response) {
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
console.log('Data: ' + data);
console.log('Status: ' + status);
return data;
})
.catch(function(response) {
console.log('something worng');
});
}
}]);
but that combination gives me an error Provider 'checkAttendee' must return a value from $get factory method. when there is a return value.
Any thoughts?
Option 1
When we work with factories the structure should be:
myApp.factory('checkAttendee', ['$http', function($http) {
var factory = {
getAttendeeInfo : function () {
return $http.get(/**/).then(function(response) {
// ..
return data;
}
}
}
return factory;
}]);
DEMO 1
Option 2
you can change factory to service and everything should work. A.e.:
myApp.service('checkAttendee', ['$http', function($http) {
this.getAttendeeInfo = function(req) {
return $http.get("/check/attendee/", {params:{"firstName":req.firstName, "lastName":req.lastName, "email": req.email, "eventID": req.eventID}})
.then(function(response) {
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
console.log('Data: ' + data);
console.log('Status: ' + status);
return data;
})
.catch(function(response) {
console.log('something worng');
throw response;
});
}
}]);
DEMO 2
Keep in mind that service extends the factory

Angular rootScope works then goes undefined on refresh - AngularFire

Scenario: I assign some values for the user at login to my rootScope. Now I want to able to use those values so that every time the user post a meeting, it should be added under his information in Firebase db.
Issue: I do this well, when I login, and i post the meeting from the user. But then as soon as the page refreshes, rootScope.currentUser becomes undefined. How can I keep rootScope.currentUser from going undefined? My Controller and my factory are below:
my controller:
myApp.controller('MeetingsController', function($scope, $firebaseObject, $firebaseArray, $rootScope, FIREBASE_URL, SomeURL){
//rootScope.currentUser.$id works the first time i post then the second it doesn't
var ref = new Firebase(FIREBASE_URL + $rootScope.currentUser.$id + SomeURL);
var meetings = $firebaseObject(ref);
$scope.meetings = meetings;
$scope.addMeeting = function(){
ref.push({
name: $scope.meetingname,
date: Firebase.ServerValue.TIMESTAMP
});
};
});//controller for around me
My Factory:
myApp.factory('Authentification', function($firebase, $rootScope, $firebaseObject, $firebaseAuth, $routeParams, $location, FIREBASE_URL){
var ref = new Firebase(FIREBASE_URL);
var auth = $firebaseAuth(ref);
auth.$onAuth(function(authUser){
if(authUser){
var firebaseUsers = new Firebase(FIREBASE_URL+'/users/'+authUser.uid);
var user = $firebaseObject(firebaseUsers);
$rootScope.currentUser = user;
} else {
$rootScope.currentUser = '';
}
});
var myObject = {
login: function(user){
return auth.$authWithPassword({
email: user.email,
password: user.pswd
});
},
logout: function(user){
return auth.$unauth();
},
requireAuth: function() {
return auth.$requireAuth();
}
};
return myObject;
});
Route:
myApp.config( ['$routeProvider', function($routeProvider){
$routeProvider.
when('/login', {
templateUrl: 'views/login.html',
controller: 'RegistrationController'
}).
when('/register',{
templateUrl: 'views/register.html',
controller: 'RegistrationController'
}).
when('/aroundme', {
templateUrl: 'views/aroundme.html' ,
controller: 'MeetingsController',
resolve: {
currentAuth: function(Authentification){
return Authentification.requireAuth();
}
}
}).
otherwise({
redirectTo: '/'
});
}]);
The issue might be that you're assigning the $firebaseObject to the $rootScope before it has finished loading. To make sure that it has loaded before binding it to the $rootScope use $loaded():
auth.$onAuth(function(authUser){
if(authUser){
var firebaseUsers = new Firebase(FIREBASE_URL+'/users/'+authUser.uid);
var user = $firebaseObject(firebaseUsers);
user.$loaded()
.then(function(data) {
$rootScope.currentUser = data;
})
.catch(function(err) {
// Handle error
});
} else {
$rootScope.currentUser = '';
}
});
From the docs:
Note that the data will not be available immediately since retrieving it is an asynchronous operation. You can use the $loaded() promise to get notified when the data has loaded.

MEAN stack pass parameter within router

I'm a newbie to MEAN stack development. Trying to follow this tutorial https://thinkster.io/mean-stack-tutorial/ to get a simple web app working. I posted my code in the following. I created a middle layer parameter called post (see router.js file) to get a particular post. In my postCtrl, I want to pass the post/postId to the factory and get the particular post.
//$scope.post = postFactory.getById(id);
According to the tutorial, the post should be detected automatically from URL route. So I wonder how should I utilize it to get the post I want? Thanks for your time in advance
AngularController.js
var app = angular.module("littleStar" , ["service", "ui.router"]);
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: "/home.html",
controller: 'mainCtrl'
})
.state('post', {
url:'/post/{id}',
templateUrl: '/post.html',
controller:'postCtrl'
});
$urlRouterProvider.otherwise('home');
}]);
app.controller("mainCtrl", ["$scope", "$http", "postFactory", function ($scope, $http, postFactory) {
postFactory.get().success(function(data){
$scope.posts = data;
});
$scope.addPost = function() {
var title = $scope.title;
var link = $scope.link;
if (!title || title === "" || !link || link === "") {
return;
}
var newPost = {
"title": title,
"link": link
}
postFactory.create(newPost)
.success(function (data) {
postFactory.get().success(function(allPosts){
$scope.posts = allPosts;
});
});
$scope.title = "";
$scope.link = "";
};
$scope.incrementPost = function(post){
post.upvotes += 1;
};
}]);
app.controller("postCtrl", ["$scope", '$stateParams', "postFactory", function($scope, $stateParams, postFactory){
//$scope.post = postFactory.get($stateParams.id);
//$scope.post = postFactory.getById($stateParams.id);
$scope.addComment = function(){
var currentComments = postFactory.post[$stateParams.id].comments;
currentComments.push({
author:$scope.author,
body: $scope.body,
upvotes: 0
});
$scope.body = "";
}
$scope.incrementComment = function(comment){
comment.upvotes += 1;
}
}]);
router.get('/posts/:post', function(req, res) {
res.json(req.post);
});
router.param('post', function(req, res, next, id) {
var query = Post.findById(id);
query.exec(function (err, post){
if (err) { return next(err); }
if (!post) { return next(new Error('can\'t find post')); }
console(id);
req.post = post;
return next();
});
});
angularService.js
var service = angular.module("service", []);
service.factory("postFactory", ["$http", function($http){
return {
get : function(){
return $http.get("/posts");
},
create: function(newPost){
return $http.post("/post", newPost);
},
delete : function(id){
return $http.delete("/post/" + id);
},
getById : function(id){
return $http.get("posts/" + id);
}
}
}]);
You should be able to make the get post route in the following way:
router.get('/posts/:post', function(req, res) {
var query = Post.findById(req.params.post);
query.exec(function (err, post){
res.json(post);
});
});

angularjs localStorageServiceProvider

I am trying to follow this tutorial
http://www.codeproject.com/Articles/784106/AngularJS-Token-Authentication-using-ASP-NET-Web-A
I don't know which angularjs package to download so that I could use localStorageService and ngAuthSettings in my angularjs code.
I am getting the following err when I run the mvc 5 asp.net vs2013 web api app.
Unknown provider: localStorageServiceProvider <- localStorageService <- authInterceptorService <- $http <- $templateRequest <- $compile
Here is my code.
var appointmentReminderApp = angular.module('appointmentReminderApp', ["ngRoute", "ui.bootstrap"]);
appointmentReminderApp.config(function ($routeProvider, $locationProvider,$httpProvider) {
$httpProvider.interceptors.push('authInterceptorService');
$locationProvider.html5Mode(true);
$routeProvider
.when("/home", {
templateUrl: "App/Home.html",
controller: "HomeController"
})
.when("/Register", {
templateUrl: "App/AuthForm/templates/register.html",
controller: "authRegisterController"
})
.when("/Login", {
templateUrl: "App/AuthForm/templates/login.html",
controller: "authLoginController"
})
.otherwise({ redirectTo: "/home" });
});
appointmentReminderApp.factory('authInterceptorService', ['$q', '$injector', '$location', 'localStorageService', function ($q, $injector, $location, localStorageService) {
var authInterceptorServiceFactory = {};
var _request = function (config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
}
var _responseError = function (rejection) {
if (rejection.status === 401) {
var authService = $injector.get('authService');
var authData = localStorageService.get('authorizationData');
if (authData) {
if (authData.useRefreshTokens) {
$location.path('/refresh');
return $q.reject(rejection);
}
}
authService.logOut();
$location.path('/login');
}
return $q.reject(rejection);
}
authInterceptorServiceFactory.request = _request;
authInterceptorServiceFactory.responseError = _responseError;
return authInterceptorServiceFactory;
}]);
appointmentReminderApp.factory('authService', ['$http', '$q', 'localStorageService', 'ngAuthSettings', function ($http, $q, localStorageService, ngAuthSettings) {
var registerUser = function (auth) {
return $http.post("/api/Account/Register", auth);
};
var loginUser = function (loginData) {
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.Password;
if (loginData.useRefreshTokens) {
data = data + "&client_id=" + ngAuthSettings.clientId;
}
var deferred = $q.defer();
$http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {
if (loginData.useRefreshTokens) {
localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: response.refresh_token, useRefreshTokens: true });
}
else {
localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: "", useRefreshTokens: false });
}
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
_authentication.useRefreshTokens = loginData.useRefreshTokens;
deferred.resolve(response);
}).error(function (err, status) {
_logOut();
deferred.reject(err);
});
return deferred.promise;
};
return {
registerUser: registerUser,
loginUser: loginUser
};
}
]);
Have you downloaded the angular local storage service module? do you have this line
<script src="scripts/angular-local-storage.min.js"></script>
in your index.html?
The required JS file doen't come bundled with Angular.
You can get it from here.
I was unable to find the CDN, will update if I find one.

Angularjs $on not firing after $rootScope.$broadcast

I have this code where two controllers are using a shared service to communicate.
var app = angular.module('AdminApp', ['ngRoute']);
app.factory('SharedService', function ($rootScope) {
var sharedService = {
userId: [],
BroadcastUserId: function (id) {
this.userId.push(id);
$rootScope.$broadcast('handleBroadcast');
}
};
return sharedService;
});
app.config(function ($routeProvider) {
$routeProvider.when('/login', {
templateUrl: "adminLogin.html"
});
$routeProvider.when('/main', {
templateUrl: 'adminMain.html'
});
$routeProvider.otherwise({
redirectTo: '/login'
});
});
app.controller('authCtrl', function ($scope, $http, $location, SharedService) {
$scope.Userid = '';
$scope.authenticate = function (user, pass) {
$http.post('http://localhost/NancyAPI/auth', {
UserName: user,
Password: pass
}).success(function (data) {
$scope.$broadcast('Token', data.Token);
$http.defaults.headers.common['Authorization'] = 'Token ' + data.Token;
$scope.Userid = data.UserId;
SharedService.BroadcastUserId($scope.Userid);
$location.path("/main");
}).error(function (response) {
$scope.authenticationError = response.error || response;
});
};
$scope.$on('handleBroadcast', function () {
console.log('on');
});
}).$inject = ['$scope', '$rootScope', 'SharedService'];
app.controller('mainCtrl', function ($scope, $http, $q, SharedService) {
$scope.tests = [];
$scope.userId = -1;
$scope.getTests = function () {
var deferred = $q.defer();
$http.get('http://localhost/NancyAPI/auth/tests/' + $scope.userId).
success(function (data) {
deferred.resolve(data);
$scope.tests = angular.fromJson(data);
}).error(function (response) {
});
};
// THIS IS NOT FIRING
$scope.$on('handleBroadcast', function () {
$scope.userId = SharedService.userId;
});
}).$inject = ['$scope', '$rootScope', 'SharedService'];
For some reason the $scope.$on is firing in the AuthCtrl controller but not in the mainCtrl.
// THIS IS NOT FIRING
$scope.$on('handleBroadcast', function () {
$scope.userId = SharedService.userId;
});
Why is this happening and how do I fix it?
I made a subtle mistake of not providing the {$rootScope} as dependency. Once I corrected that, it worked for me. I used Inline Array Annotation mechanism to achieve the same.

Resources