AngularJS change location is not working - angularjs

I'm new in ionic
I'm trying to do a simple switch between two views in a login app:
index.html
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Login App</h1>
</ion-header-bar>
<ion-content>
<div class="list list-inset">
<label class="item item-input">
<input type="text" placeholder="Email" ng-model="data.email">
</label>
<label class="item item-input">
<input type="password" placeholder="Password" ng-model="data.password">
</label>
</div>
<button class="button button-block button-calm" ng-click="postLogin()">Login</button>
</ion-content>
</ion-pane>
logincontroller.js
app.controller('loginCtrl', function ($scope,$http,$location)
{
$scope.data = {};
$scope.postLogin = function ()
{
var data =
{
email: $scope.data.email,
password: $scope.data.password
};
console.log('bonjour');
$http.post("http://localhost/authproject/public/api/auth/login", data)
.then(
function(response){
// success callback
console.log('success');
$location.path('/map');
},
function(response){
// failure callback
console.log('error');
$location.path('/index');
}
);
}
When I click on a button Login the url change but the page doesn't change
Could someone tell me how do I solve this ? Thanks in advance :)

In your app.js add a state for map like this (with your own templateUrl and controller value). Make sure to add $stateProvider in the config(). Also, include ui.router to your dependencies. Something like this:
angular.module('starter', ['ionic', 'starter.controllers', 'starter.directives', 'ui.router'])
.config(function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider){
$stateProvider
.state('map', {
url: '/map',
templateUrl: 'app/views/map.html',
controller: 'MapController'
});
...
And in your index.html:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js"></script>

Try this
app.controller('loginCtrl', function ($scope,$http,$location,$state) {
$scope.data = {};
$scope.postLogin = function ()
{
var data =
{
email: $scope.data.email,
password: $scope.data.password
};
console.log('bonjour');
$http.post("http://localhost/authproject/public/api/auth/login", data)
.then(
function(response){
// success callback
console.log('success');
$location.path('/map');
},
function(response){
// failure callback
console.log('error');
$state.go('main');
});
})
Add a state in app.js
.config(function($stateProvider,$urlRouterProvider){
.state('main', {
url:'/main',
templateUrl:'templates/main.html',
controller:'yourCtrl'
})
$urlRouterProvider.otherwise('/index');
})
Now make in template folder make a page for named main.html

Related

How to correctly reinitiate view with $state.go from another view

I am attempt to send users from one state to another with this method:
$state.go('splash');
This works correctly, however, when users are sent to my splash view the code does not reinitiate.
This is the html of the splash state:
<ion-view hide-nav-bar="true">
<ion-content class="splash-screen" scroll="false">
<div class="loading">
<i class="fa fa-circle-o-notch fa-spin fa-5x fa-fw"></i>
</div>
</ion-content>
</ion-view>
<script id="login.html" type="text/ng-template">
<ion-modal-view>
<ion-header-bar class="bar bar-header bar-stable">
<h1 class="title">Login</h1>
</ion-header-bar>
<ion-content>
<div class="list padding">
<div class="error" ng-if="errors">
<p ng-bind-html="error_message"></p>
</div>
<label class="item item-input">
<input ng-model="data.password" type="password" placeholder="Password">
</label>
<button class="button button-full button-positive" ng-click="login(data)">Login</button>
</div>
</ion-content>
</ion-modal-view>
</script>
This is the controller for the view:
angular.module('app.controllers', [])
.controller('SplashCtrl', function($scope, $http, $state, $ionicModal, $ionicLoading, $ionicPlatform, $timeout, $localstorage, appAPI) {
$scope.data = {};
$scope.data.password = '';
$ionicModal.fromTemplateUrl("login.html", {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.login = function(data) {
alert(data.password);
};
$ionicPlatform.ready(function() {
$scope.openModal();
});
});
When users visit the splash view the first time, the modal loads as intended, however, when they are directed there from the $state.go - the modal does not load.
Any thoughts how I can get this to work correctly?
Multiple Calls to $ionicPlatform.ready()
Unfortunately, other callbacks passed to the function are silently ignored. (ARGH!)1
In addition to taking a callback function as a parameter, it returns a promise for the platform being ready.
Use the promise:
$ionicPlatform.ready().then(function() {
$scope.openModal();
});
I hope you are looking to reload your 'SplashCtrl' controller when the user is routed to the 'splash' state.
If so, try this $state.go('splash', {}, {reload: true});
You haven't shared your entire project so I can't tell really. It seems your structure is a bit off. You should only have one ionicPlatform.ready() and it should be to setup the environment. Once done it should forward the user to your first view, no open a modal.
This is how I check that in my app. The platform ready function has $state.go('app.calendar'); which is my first view (assuming they are logged in) - if they are not logged in the init function returns an error from the promise and the statechange error code forwards them to the login signup page.
State controller
.state('app', {
url: '/app',
cache: false,
abstract: true,
templateUrl: 'templates/tabs.html',
controller: 'TabCtrl',
resolve: {
user: function (UserService) {
var value = UserService.init();
return value;
}
}
})
// Calendar
.state('app.calendar', {
url: "/calendar",
cache: true,
views: {
'calendar-tab': {
templateUrl: 'templates/calendar.html',
controller: 'CalendarController'
}
}
})
Check if logged in.
function init(){
var deferred = $q.defer();
if (loggedIn()) {
deferred.resolve(currentUser);
} else {
deferred.reject({error: "noUser"});
}
return deferred.promise;
};
React to the state error - app-first is the login or signup page.
$rootScope.$on('$stateChangeError',
function (event, toState, toParams, fromState, fromParams, error) {
console.log('$stateChangeError ' + error && (error.debug || error.message || error));
// if the error is "noUser" the go to login state
if (error && error.error === "noUser") {
event.preventDefault();
$state.go('app-first', {});
}
}
);

Posting data to my controller for API call - Ionic

Trying to get my form inputs into my controller so that I can pass them in my API call.
I have this form:
<ion-content class="has-subheader">
<form ng-submit="storeProject()">
<div class="list">
<label class="item item-input">
<span class="input-label">Title</span>
<input type="text" ng-model="projectData.title">
</label>
<label class="item">
<button class="button button-block button-positive" type="submit">Create Project</button>
</label>
</div>
</form>
</ion-content>
I then have this controller:
.controller('ProjectCtrl', function($scope, $auth, $http, $ionicPopup, $rootScope) {
$scope.projectData = {};
$scope.storeProject = function(projectData) {
console.log("add project: ", $scope.projectData);
};
})
And this in my app.js:
.state('app.new_project', {
url: '/projects/new',
data: {
permissions: {
except: ['anonymous'],
redirectTo: 'app.auth'
}
},
views: {
'menuContent': {
templateUrl: 'templates/new_project.html',
controller: 'ProjectCtrl'
}
}
});
I have my API working great, but just need to be able to get my values from the form to post.
Need to be able to do projectData.title etc.
I always get undefined in the log.
Replace
$scope.storeProject = function(projectData) {
by
$scope.storeProject = function() {
Or replace
ng-submit="storeProject()"
by
ng-submit="storeProject(projectData)"
That said, I don't see how your posted code could log undefined. My guess is that your actual code is
console.log("add project: ", projectData);

AngularJS UI freeze during polling $timeout $scope updates

I have an app with a simple view that contains a list of a few items.
<ion-view view-title="App">
<ion-content>
<div class="list">
<div ng-repeat="group in groups">
<div class="item item-divider">
{{group.name}}
</div>
<div class="item row" ng-repeat="item in group.items" ng-click="live(item.id)">
<div class="col-75">
</div>
<div class="col">
</div>
</div>
</div>
</div>
</ion-content>
</ion-view>
I fetch these items from a service that makes a $http get of a json array from the server, and inside the controller I need to update this list every 10 seconds.
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state("home", {
url: "/home",
templateUrl: "home.html",
controller: "homeCtrl",
resolve: {
data: function(appDataService){
return appDataService.getData();
}
}
})
;
$urlRouterProvider.otherwise("/home");
});
.factory('appDataService', function ($http) {
return {
getData: function () {
return $http.get(HOST + "/ionic-proof.ashx").then(function (response) {
return response;
});
},
};
})
.controller("homeCtrl", function($state, $scope, data, appDataService, $timeout){
$scope.groups = data.data.groups;
(function refresh(){
appDataService.getData().then(function(response){
$scope.groups = response.data.groups;
$timeout(refresh, 10000);
});
})();
$scope.live = function(id){
$state.go("event", {id: id});
};
})
The problem is, everytime the $scope.groups inside the refresh() function is executed, I get a short "freeze" in the UI, which is quite noticeable (e.g. if I am scrolling the list up and down).
Any ideas what I might be doing wrong?
Thanks in advance

ui-router $stateProvider.state.controller don't work

The SignupCtrl controller is not binding to signup view. Even when i press the submit button it don't work. But when i place ng-controller=SignupCtrl in the form tag it works. Just wondering why ui-router state parameter controller was not working.
index.html
<html class="no-js" ng-app="mainApp" ng-controller="MainCtrl">
<head> ....
</head>
<body class="home-page">
<div ui-view="header"></div>
<div ui-view="content"></div>
<div ui-view="footer"></div>
...
signup.html
<div class="form-container col-md-5 col-sm-12 col-xs-12">
<form class="signup-form">
<div class="form-group email">
<label class="sr-only" for="signup-email">Your email</label>
<input id="signup-email" type="email" ng-model="user.email" class="form-control login-email" placeholder="Your email">
</div>
<!--//form-group-->
<div class="form-group password">
<label class="sr-only" for="signup-password">Your password</label>
<input id="signup-password" type="password" ng-model="user.password" class="form-control login-password" placeholder="Password">
</div>
<!--//form-group-->
<button type="submit" ng-click="createUser()" class="btn btn-block btn-cta-primary">Sign up</button>
<p class="note">By signing up, you agree to our terms of services and privacy policy.</p>
<p class="lead">Already have an account? <a class="login-link" id="login-link" ui-sref="login">Log in</a>
</p>
</form>
</div><!--//form-container-->
app.js
angular
.module('mainApp', [
'services.config',
'mainApp.signup'
])
.config(['$urlRouterProvider', function($urlRouterProvider){
$urlRouterProvider.otherwise('/');
}])
signup.js
'use strict';
/**
* #ngdoc function
* #name mainApp.signup
* #description
* # SignupCtrl
*/
angular
.module('mainApp.signup', [
'ui.router',
'angular-storage'
])
.config(['$stateProvider', function($stateProvider){
$stateProvider.state('signup',{
url: '/signup',
controller: 'SignupCtrl',
views: {
'header': {
templateUrl: '/pages/templates/nav.html'
},
'content' : {
templateUrl: '/pages/signup/signup.html'
},
'footer' : {
templateUrl: '/pages/templates/footer.html'
}
}
});
}])
.controller( 'SignupCtrl', function SignupController( $scope, $http, store, $state) {
$scope.user = {};
$scope.createUser = function() {
$http({
url: 'http://localhost:3001/users',
method: 'POST',
data: $scope.user
}).then(function(response) {
store.set('jwt', response.data.id_token);
$state.go('home');
}, function(error) {
alert(error.data);
});
}
});
There is a working plunker. Firstly, check this Q & A:
Are there different ways of declaring the controller associated with an Angular UI Router state
Where we can see, that
controller does not belong to state. It belongs to view!
This should be the state definition:
$stateProvider.state('signup',{
url: '/signup',
//controller: 'SignupCtrl',
views: {
'header': {
templateUrl: 'pages/templates/nav.html'
},
'content' : {
templateUrl: 'pages/signup/signup.html',
controller: 'SignupCtrl',
},
'footer' : {
templateUrl: 'pages/templates/footer.html'
}
}
});
Check it here
You need a template to bind a controller.
In the docs ui-router Controllers
Controllers
You can assign a controller to your template. Warning: The controller
will not be instantiated if template is not defined.

Satellizer Http Interceptor

Currently I'm using satellizer library to authenticate using json web token. On the backend, I have tested the api and the authentication and everything is working. By the way Im using Twitter authentication.
While on the frontend, which the angular part,After I have authenticated with twitter and successfully redirect to home page, I couldn't get user's information whenever i go to /profile, it doesnt render the user's information and when I check the network tab on google chrome, angular doesnt even call the /api/me route from the backend.
I believe it has something to do with Http interceptor. The authorization header is set as x-access-token both on frontend and backend.
Here's the code.
app.js
angular.module('MyApp', [ 'ngMessages','ngRoute', 'ui.router','satellizer'])
.config(function($authProvider) {
// Twitter
$authProvider.authHeader = 'x-access-token';
$authProvider.httpInterceptor = true; // Add Authorization header to HTTP request
$authProvider.tokenPrefix = 'twitterAuth'; // Local Storage name prefix
$authProvider.twitter({
url: '/auth/twitter',
type: '1.0',
popupOptions: { width: 495, height: 645 }
});
})
.config(function($stateProvider, $urlRouterProvider,$locationProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/views/home.html'
})
.state('login', {
url: '/login',
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.state('profile', {
url: '/profile',
templateUrl: 'app/views/profile.html',
controller: 'ProfileCtrl',
})
.state('logout', {
url: '/logout',
template: null,
controller: 'LogoutCtrl'
})
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode(true);
})
the controllers
login.js
angular.module('MyApp')
.controller('LoginCtrl', function($scope, $auth) {
$scope.authenticate = function(provider) {
$auth.authenticate(provider);
};
});
profile.js
angular.module('MyApp')
.controller('ProfileCtrl', function($scope, $auth, Account) {
$scope.getProfile = function() {
Account.getProfile()
.success(function(data) {
$scope.user = data;
})
};
});
services
account.js
angular.module('MyApp')
.factory('Account', function($http) {
return {
getProfile: function() {
return $http.get('/api/me');
}
};
});
Views
profile.html
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">Profile</div>
<div class="panel-body">
<form method="post">
<div class="form-group">
<label class="control-label">Profile Picture</label>
<img class="profile-picture" ng-src="{{user.picture || 'http://placehold.it/100x100'}}">
</div>
<div class="form-group">
<label class="control-label"><i class="ion-person"></i> Display Name</label>
<input type="text" class="form-control" ng-model="user.displayName" />
</div>
<div class="form-group">
<label class="control-label"><i class="ion-at"></i> Email Address</label>
<input type="email" class="form-control" ng-model="user.email" />
</div>
</form>
</div>
</div>
</div>
This is where the user's information from twitter authentication should render, on the backend everything is showing when I'm using Chrome postman.
I've been pulling my hair for the past 4 hours, so what did I do wrong over here?
I am missing a call to ProfileCtrl's $scope.getProfile. Try this:
angular.module('MyApp')
.controller('ProfileCtrl', function($scope, $auth, Account) {
Account.getProfile()
.success(function(data) {
$scope.user = data;
});
});

Resources