Why is my controller breaking my code? - javascript

I am running a ionic project and I visualize it live with the Ionic Lab tool. It is pretty good because each time I modify a html doc, it shows live what's going on.
Now, I have inserted a controller at the bottom of my controllers.js and it just breaks my project. What I mean by that is that if I take the code off of the controllers.js file, the project shows up normally but if I put it, it justs make the entire project go blank. Like if nothing was on it.
Here is the code I added :
.controller('AccountCtrl', function($scope, $state, $cordovaOauth) {
$scope.$on('$ionicView.enter', function() {
//Authentication details.
JSON.stringify(firebase.auth().currentUser));
//Get logged in user credentials.
var user = firebase.auth().currentUser;
var name, email, photoUrl, provider;
if (user != null) {
name = user.displayName;
email = user.email;
photoUrl = user.photoURL;
provider = user.provider;
}
//Set Profile Image.
profileImage = photoUrl;
//Set Profile Name.
profileName = name;
//It is now up to you to set provider and email!
})
});
And here is my complete document :
angular.module('starter.controllers', [])
.controller('LoginCtrl', function($scope, $state, $cordovaOauth) {
$scope.signIn = function() {
$state.go('tab.dash');
};
$scope.facebook = function() {
var facebookAppId = "198040820571843";
$cordovaOauth.facebook(facebookAppId, ["public_profile", "email"]).then(function(response) {
var credential = firebase.auth.FacebookAuthProvider.credential(response.access_token);
loginWithCredential(credential, 'Facebook');
}, function(error) {
//User cancelled login. Hide the loading modal.
});
}
$scope.twitter = function() {
var twitterKey = "aJWByCgPhUgYZJMojyFeH2h8F";
var twitterSecret = "XxqKHi6Bq3MHWESBLm0an5ndLxPYQ2uzLtIDy6f9vgKKc9kemI";
$cordovaOauth.twitter(twitterKey, twitterSecret).then(function(response) {
var credential = firebase.auth.TwitterAuthProvider.credential(response.oauth_token,
response.oauth_token_secret);
loginWithCredential(credential, 'Twitter');
}, function(error) {
//User cancelled login. Hide the loading modal.
});
};
loginWithCredential = function(credential, provider) {
firebase.auth().signInWithCredential(credential)
.then(function(response) {
//User logged in through provider.
$state.go('tab.dash');
})
.catch(function(error) {
//Show error message.
var errorCode = error.code;
});
};
});
.controller('AccountCtrl', function($scope, $state, $cordovaOauth) {
$scope.$on('$ionicView.enter', function() {
//Authentication details.
JSON.stringify(firebase.auth().currentUser));
//Get logged in user credentials.
var user = firebase.auth().currentUser;
var name, email, photoUrl, provider;
if (user != null) {
name = user.displayName;
email = user.email;
photoUrl = user.photoURL;
provider = user.provider;
}
//Set Profile Image.
profileImage = photoUrl;
//Set Profile Name.
profileName = name;
//It is now up to you to set provider and email!
})
});
I really don't understand what is going on, it just breaks everything !
And I call that controller in the app.js :
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html'
}
},
controller: 'AccountCtrl'
})
If anybody has any help... Thanks !
EDIT , in the console, here is the error :
?ionicplatform=android:29 Uncaught SyntaxError: Unexpected token . http://localhost:8100/js/controllers.js Line: 43console.(anonymous function) # ?ionicplatform=android:29
controllers.js:43 Uncaught SyntaxError: Unexpected token .
It is the line that starts my controller of course...

Two issues:
You have a trailing semicolon (;) on the controller LoginCtrl.
Your AcctCtrl cannot be fluently attached to your angular module because of that trailing semicolon on the controller above it.
Second,
This line has one too many closing )
JSON.stringify(firebase.auth().currentUser));
It should be:
JSON.stringify(firebase.auth().currentUser);

From line:41 remove the simi-colon, this breaks the chain of reference to angular.

Related

$window resets my service

I am creating an login page using Angular. After I process my login in the backend, I set the values in MyService from my LoginCtrl and then move to the next page using $window.location.href= 'main.jsp'; . But when I call the values which I set in LoginCtrl from HomeCtrl, the values are empty?
I know that Services are singletons and will maintain the same state throughout the app. But in this case, It jut resets. I think it is because of using $window.location.href. Please help me solve my problem.
This is my service ( MyService ):
app.service('MyService', function() {
var user = {
name: '',
permissions: ''
};
this.getUser = function() {
return user;
}
this.setUser = function(userr) {
this.user = userr;
}
});
This my LoginCtrl: ( I've just posted the http.post part)
$http({
method: 'POST',
url: 'login',
data: JSON.stringify($scope.user),
headers: {
'Content-Type': 'application/json'
}
}).success(function(data) {
if (!("failure" == data)) {
console.log(data);
var user = MyService.getUser();
user.name = data.name;
user.permissions = data.permissions;
console.log(user);
console.log(MyService.getUser());
$window.location.href = 'main.jsp';
// MyService.changeLocation('main.jsp', true);
} else {
$scope.information = "Invalid username/password!"
}
}).error(function(data) {
console.log(data);
});
And this is my HomeCtrl:
app.controller('HomeCtrl', function($scope, $http,MyService) {
console.log(MyService.getUser());
var user = MyService.getUser();
$scope.flashMessage="Hello " + user.name;
});
Here user.name is empty.
You are changing your web page. The angular application is not persisted across the website boundary; remove the alteration to the window.location.href.
In order to simulate page changing in Angular consider using the official router (shipped with Angular 1.4+), ngRoute or Angular UI Router. These solutions use the HTML History Api and fallback to hashbang URLs to emulate the sort of thing you're trying to achieve.
This ends up creating a single-page application, which is what Angular is designed for.
In LoginCtrl, while reaching the success callback, you are not setting the response value(data in your case) to user object in MyService service.
You are getting the user object from the Service by
var user = MyService.getUser();
But setting the values to that object will not set the user object in the Service.
You need to use MyService.getUser(user); to set values in your service and the same will be available in your HomeCtrl
$http({
method: 'POST',
url: 'login',
data: JSON.stringify($scope.user),
headers: {
'Content-Type': 'application/json'
}
}).success(function(data) {
if (!("failure" == data)) {
console.log(data);
var user= {};
user.name = data.name;
user.permissions = data.permissions;
MyService.getUser(user); //set the values for user
var obj= MyService.getUser(); //get the values for user
console.log(obj);
//should display user object
//with respective name and permissions should be available
console.log(MyService.getUser());
$window.location.href = 'main.jsp';
// MyService.changeLocation('main.jsp', true);
} else {
$scope.information = "Invalid username/password!"
}
}).error(function(data) {
console.log(data);
});
UPDATE:
The reason why your code doesnt seem to work is: you are using $window incorrectly to change the route. $window.location.href = 'main.html' is somehow changing the route outside angular's context and hence not running the HomeCtrl. To fix this, you need to do the following:
First, define routes for your angular application (preferabbly using ui-router)
app.config(function($stateProvider){
$stateProvider
.state('login',{
url:'/',
templateUrl:'login.html',
controller:'LoginCtrl'
})
.state('main',{
url:'/main',
templateUrl:'main.html',
controller:'HomeCtrl'
})
.state("otherwise", { url : '/'})
})
Use $location.url('/main'). Notice it is same as the url pattern we defined for state: main. Or better, you should use $state.go('home'); to redirect the user to desirable state
Here's a working plunkr
Hope this helps!

firebaseAuth with Angular: User Login

I am using Angular (1.3.5) and Firebase to write a toy blog program, and am currently struggling with the user login part.
I first created an Angular module:
var blogApp = angular.module('blogApp', ['ngRoute', 'firebase', 'RegistrationController']);
Then on top of blogApp, I created a controller called ** RegistrationController **:
blogApp.controller('RegistrationController', function ($scope, $firebaseAuth, $location) {
var ref = new Firebase('https://myAppName.firebaseio.com');
// var authLogin = $firebaseAuth(ref);
$scope.login = function(){
ref.authWithPassword({
email: $scope.user.email,
password: $scope.user.password
}, function(err, authData) {
if (err) {
$scope.message = 'login error';
} else {
$scope.message = 'login sucessful!';
}
});
}; // login
}); //RegistrationController
I attached the login() method to ng-submit in my user-login form in the scope of RegistratinController.
When I click to submit the login form, the form does not make any response, without any errors showing.
The login form works only when I click the 'Submit' button twice - why is this? confusing
You are using the Firebase JavaScript library and not AngularFire for the login methods.
You need to pass the Firebase reference into the $firebaseAuth binding.
var auth = $firebaseAuth(ref);
From there you can call auth.$authWithPassword.
$scope.login = function(){
auth.$authWithPassword({
email: $scope.user.email,
password: $scope.user.password
}, function(err, authData) {
if (err) {
$scope.message = 'login error';
} else {
$scope.message = 'login successful!';
}
});
}; // login
AngularFire is an Angular binding for the Firebase Library that handles auto syncing over objects and arrays. AngularFire also handles when to call $scope.apply to properly update the view.
In your case, the login code is working the first click, but it doesn't get applied to the page. You can wrap this code in a $timeout, but it would be better to use the $firebaseAuth service.
Thanks to user jacobawenger, for the solution he posted here:
Can't get new password authentication methods to work in AngularFire 0.9.0?
This works as expected:
myApp.controller('RegistrationController',
function($scope, $firebaseAuth, $location) {
var ref = new Firebase('https://myApp.firebaseio.com');
var simpleLogin = $firebaseAuth(ref);
$scope.login = function() {
simpleLogin.$authWithPassword({
email: $scope.user.email,
password: $scope.user.password
}).then(function() {
$location.path('/mypage');
}, function(err) {
$scope.message = err.toString();
});
} // login
}); // RegistrationController

Route resolve promise, not fully resolved - angularjs

So, what I'm trying to do here is something simple:
check the role of the loggedUser on each route (with a resolve that sets the user if a token or login credentials are valid on the backend)
redirect to the intended route
if not allowed for a route, redirect to a different route
In my route provider I have something like
$routeProvider
...
.when('/admin', {
templateUrl: 'views/admin/dashboard.html',
controller: 'AdminDashboardCtrl',
resolve: {
checkLoggedUser: check
}
})
...
where ckeck is this function
var check = function($rootScope, $q, AuthService) {
var deferred = $q.defer();
if($rootScope.loggedUser) {
return;
}
console.log('inside resolve check')
AuthService.check().success(function(data) {
$rootScope.loggedUser = data.user;
deferred.resolve(data.user);
});
console.log('finished check')
return deferred.promise;
};
And my AuthService.check() is this function
check: function()
{
var authtoken = StorageService.get('authtoken');
if(!authtoken) {
$location.path('login');
}
console.log('before returning');
return $http.post($rootScope.base + 'auth/authenticate', { 'authtoken': authtoken });
},
In my .run(function I have
$rootScope.$on('$routeChangeSuccess', function() {
setIntendedUrl();
console.log($rootScope.loggedUser);
console.log($location.path());
});
and setIntendedUrl() check for the loggedUser and redirects to the correct page (or, in what I'm trying to accomplish, redirect to a different page if not allowed, for example the loggedUser has role = 1, can visit only the routes /admin, if a user has role = 2, and the requested path is /admin, he has to be redirected to /user)
So after all this code, when the app run this is my log in the console (see in the code where are they called)
inside resolve check app.js:29
before returning authservice.js:24
finished check app.js:36
intended: /admin/agents/create app.js:149 <--- here is where I redirect the user
Object {id: "21", name: "Kyle", surname: "Butler", roleId: "2"...} app.js:167
/admin/agents/create <--- requested path
This is not what I was expecting, so the first three logs are good, the third doesn't wait the promise to be returned (so I don't have a loggedUser) then the AuthService:check() returns the user and it's everything done at this point, the user with role = 2 is in a route that is not allowed to see.
Just to complete the code, this is the setIntendedUrl function
var setIntendedUrl = function() {
intended = $location.path();
console.log('intended: ' + intended)
if(intended !== '/login') {
if($rootScope.loggedUser && $rootScope.loggedUser.roleId === '1' && !/^\/admin*/.test(intended)) {
intended = '/admin';
} else if($rootScope.loggedUser && $rootScope.loggedUser.roleId === '2' && !/^\/manager*/.test(intended)) {
intended = '/manager';
}
StorageService.set('intended', intended);
//$location.path(intended);
}
};
What I am doing wrong? Why the user in the check function is not resolved before the other code is executed?
Can you make use of session/locals storage or $rootScope where you can store the users authorization object with given routes, permission info once user logged in.
Now is route resolve or run() block you can retrieve the user auth object perform authorization action.
e.g.
.run(['sessionService', '$rootScope', '$location', function(sessionService, $rootScope, $location) {
$rootScope.$on( "$routeChangeStart", function(event, next, current) {
var currentUser = sessionService.get('user_details');
if(next.taskAccess && next.taskAccess != ""){
var hasPerm = $rootScope.getPermission(next.taskAccess);
if(!hasPerm){
$location.path('/unauthorized');
}
}
});
}]);

How do I access currentUser from Controllers?

Here's my initializer:
...
Ember.SimpleAuth.Session.reopen({
currentUser: function() {
var userId = this.get('user_id');
if (!Ember.isEmpty(userId)) {
return container.lookup('store:main').find('user', userId);
}
}.property('user_id')
});
...
Controller:
isAdmin: function() {
var session = this.get('session.currentUser'),
role = session.get('role'); // 'role' is undefined
return role.get('name') == "Administrator";
}.property()
But when I tried from Templates:
{{session.currentUser.role.name}}
It works perfectly.
How do I access the currentUser to all Controllers or even in Routes?
I think it's because session.currentUser is a promise. Try this in your controller:
isAdmin: function() {
return this.get('session.currentUser').then(function(r) {
return r.get('role.name') == 'Administrator';
});
}.property()
Why don't you add isAdmin to your SimpleAuth Session:
isAdmin: function() {
return #get('current_user.role.name') == 'Administrator';
}.property('current_user')
Then you should be able to do
{{session.isAdmin}}
in your templates.
while login or register save user information in codeigniter session.
then access current login user information form session across the pages.
$userinfo = array(name=>'abc','userid'=>234);
$this->session->set_userdata($userinfo );//use for store user inforamtion
$current = $this->session->userdata('userid'); //for access
echo $current;

firebase simple login tutorial missing user

Tutorial: http://www.thinkster.io/angularjs/wBhtRLWHIR/6-authenticating-users-with-a-service
I'm following this tutorial and it seems like I'm losing my user as soon as they register.
Here is my auth.js factory:
'use strict';
app.factory('Auth', function($firebaseSimpleLogin, FIREBASE_URL, $rootScope){
var ref = new Firebase(FIREBASE_URL);
var auth = $firebaseSimpleLogin(ref);
var Auth = {
register : function(user) {
return auth.$createUser(user.email, user.password);
},
signedIn : function() {
// PROBLEM: authUser is always null
console.log(auth.user);
return auth.user !== null;
},
logout : function () {
auth.$logout();
}
};
$rootScope.signedIn = function () {
return Auth.signedIn();
};
return Auth;
});
Here is my auth.js controller:
'use strict';
app.controller('AuthCtrl', function($scope, $location, Auth){
if (Auth.signedIn()) {
$location.path('/');
}
$scope.register = function () {
Auth.register($scope.user).then(function (authUser) {
console.log(authUser);
$location.path('/');
});
};
});
The console.log under signedIn in the factory is always null. Any idea where the disconnect is? The registration itself is working fine, and authUser is populated in the console.log in the controller when registering.
The latest documentation for Angularfire says that the $createUser method of $firebaseSimpleLogin returns a promise but it doesn't mention any parameters being passed to the then callback.
You can use the $getCurrentUser method to get the current user after the user registers.
The tutorial needs to be updated and you should always be checking the documentation for whatever libraries you're using yourself.
Your code for signedIn should look like this:
Auth.signedIn = function() {
auth.$getCurrentUser().then(function(currentUser) {
console.log(currentUser);
}, function() {
console.log('error');
});
};
I found a very similar question that is further along in the tutorial :can't show logout button after $createUser
In the answer I learned that angularfire used to automatically log the user in after it was created. Apparently now it no longer does that which is why the auth.user in signedIn was null.
I am now doing the same tutorial. This code (in auth controller) worked for me:
$scope.register = function () {
Auth.register($scope.user).then(function (authUser) {
console.log(authUser);
Auth.login($scope.user);
$location.path('/');
});
};
I'm a total n00b, but what (I think) this is doing is authenticating the user, then running a function that logs the user in right after. Logout button is now functioning as expected.

Categories