Related
Below is app.js file contain myApp module. I am facing issue with $scope variable not updated on view file which is rendered using $state.
I am calling showArticles function on ng-change event from one of view file which got rendered using $state.go statement. This view rendered after user login. All code snap given below. Also facing same issue after AJAX success response $scope not getting updated on view file.
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider){
$stateProvider.state('settings', {
url: '/settings',
templateUrl: 'templates/setting.html',
controller: 'adminCtrl',
})
.state('profile', {
url: '/profile',
templateUrl: 'templates/profile.html',
controller: 'adminCtrl',
})
.state('account', {
url: '/account',
templateUrl: 'templates/account.html',
controller: 'adminCtrl',
cache: false
})
.state('articleList', {
url: '/articles',
controller: 'adminCtrl',
cache: false,
templateUrl: 'templates/articleList.html',
})
.state('addArticle', {
url:'/addArticle',
templateUrl : 'templates/addArticle',
controller: 'adminCtrl',
cache: false
})
$urlRouterProvider.otherwise('/settings');
});
myApp.run(function($rootScope, $state, $location, AuthenticationService){
//array of route that dont need authentication
var routeThatDontNeedAuth = ['/settings'];
var routeClean = function(route)
{
//alert(route); alert();
if(routeThatDontNeedAuth.indexOf(route) !== -1){ alert('aaa');
return false;
}
else{
return true;
}
}
$rootScope.$on('$stateChangeStart', function(event, next, current){
if(routeThatDontNeedAuth.indexOf($location.url()) < 0)
{
if(!AuthenticationService.isLoggedIn()){
//$state.go('settings');
//alert('not logged in and page is not login page');
}
}
});
});
myApp.factory('AuthenticationService', ['$http', '$state', function($http, $state){
return{
isLoggedIn: function(){ alert('Aut ser called');
$http({
url: 'http://127.0.0.1:8081/cUlI',
method: 'GET'
}).then(function(response){
alert('testtt');console.log(response);
if(!response.data.loggedIn)
{
$state.go('settings');
}
})
}
};
}]);
myApp.controller('adminCtrl', ['$scope', '$http', '$state', 'getArticleData', function($scope, $http, $state, getArticleData){
$scope.addArticle = function(){
$state.go('addArticle');
}
// get website list
$scope.showArticles = function(){
/*$scope.articleList = 'this is default article scope value';
alert($scope.articleList)
$scope.$applyAsync(function() {
$scope.articleList = "Another value rest"; alert($scope.articleList)
});*/
$http({
method: "GET",
url: "http://127.0.0.1:8081/articleList",
params: {
website:$scope.website
}
}).then(function(responseData){
if(responseData.data.status == 'success')
{
console.log('test dataaa');
console.log(responseData);
alert('page should modified')
alert('This is test');
$scope.articleList = {id:'test', name: 'article list'};//responseData.data.data;
$scope.artLs = "I am testt model";
$state.go('articleList', 'cache: false');
}
})
}
$scope.adminLogin = function(){
var uname = $scope.username;
var pass = $scope.password ;
alert(uname+'--'+pass);
$http({
method : "GET",
url : "http://127.0.0.1:8081/adminLogin",
params: {
username : uname,
pwd: pass
}
}).then(function(response) {
console.log('succes',response);
if(response.data.status == 'success')
{
$http({
method: "GET",
url: "http://127.0.0.1:8081/webSiteList"
}).then(function(responseData){
if(responseData.data.status == 'success')
{
$scope.sara = 'testsara';
$scope.websiteData = {id : 'a', name: 'test'}; // responseData.data.data;
console.log('scope website data', $scope.websiteData);
$state.go('account', 'cache: false');
}
});
}
else
{
}
}, function(response) {
console.log('error',response)
});
}
}]);
showArticles functions get called on ng-change event from account view:
<div id="main-container" class="col-md-12 container" >
<div class="col-md-1"></div>
<div class="col-md-10">
<div class="main-body">
<div class="content">
<div class="col-md-2"></div>
<div class="col-md-8">
<h2 class="text-center">Article Listing page modified</h2>
<div class="vt-add-article">
<button type="button" ="btn btn-default text-center" ng-click="addArticle();">Add</button>
</div>
<div class="vt-article-list">
{{articleList}}
<br>
{{artLs}} -- exp value
</div>
</div>
<div class="col-md-2"></div>
</div>
</div>
</div>
<div class="col-md-1"></div>
</div>
Main Index .html file :
<html>
<head>
<meta charset="utf-8">
<title>Welcome to Vidarbha Tigers Content Panel</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="/angularp/router/css/admin.css" />
<script src="/angularp/router/js/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="/angularp/router/js/app.js"></script>
</head>
<body ng-app="myApp" ng-controller="adminCtrl">
<header>
<div class="col-md-12">
<div class="col-md-1"></div>
<div class="vt-header-content col-md-10">
<div class="vt-header-logo">
<!--<img src="/images/logo.jpg" class="img-rounded" alt="Vidarbha Tiger"> -->
</div>
<div class="vt-header-tag"><h2><!--Vidarbha Tigers--></h2></div>
</div>
<div class="col-md-1"></div>
</div>
<hr/>
</header>
<div ui-view></div>
</body>
</body>
</html>
Kindly let me know if I am missing anything in my code. I am new to angular js and facing few issues which are unknown to me
ok, I understand your issue. Your $scope variable is getting reset everytime you call a view. Hence, you dont see any value. You will have to save the value and then retrieve it when your view gets loaded. I have updated your code below, try and let me know if it works or not
SOLUTION 1:
Create one more factory:
myApp.factory('persistService', ['$rootScope', function($rootScope){
var articleList = '';
return{
saveArticleList: function(data) {
articleList = data;
},
getArticleList: function() {
return articleList;
}
};
}]);
Then in your controller include the above service and save the articleList and when you go to your new view, intialize your articleList using the 'persistService' as below :
myApp.controller('adminCtrl', ['$scope', '$http', '$state', 'persistService', 'getArticleData', function($scope, $http, $state, getArticleData, persistService){
//Initialize your articleList
$scope.articleList = persistService.getArticleList();
$scope.addArticle = function(){
$state.go('addArticle');
}
// get website list
$scope.showArticles = function(){
/*$scope.articleList = 'this is default article scope value';
alert($scope.articleList)
$scope.$applyAsync(function() {
$scope.articleList = "Another value rest"; alert($scope.articleList)
});*/
$http({
method: "GET",
url: "http://127.0.0.1:8081/articleList",
params: {
website:$scope.website
}
}).then(function(responseData){
if(responseData.data.status == 'success')
{
console.log('test dataaa');
console.log(responseData);
alert('page should modified')
alert('This is test');
//Save your data
persistService.setArticleList('This is a test');
//$scope.articleList = {id:'test', name: 'article list'};//responseData.data.data;
$scope.artLs = "I am testt model";
$state.go('articleList', 'cache: false');
}
})
}
$scope.adminLogin = function(){
var uname = $scope.username;
var pass = $scope.password ;
alert(uname+'--'+pass);
$http({
method : "GET",
url : "http://127.0.0.1:8081/adminLogin",
params: {
username : uname,
pwd: pass
}
}).then(function(response) {
console.log('succes',response);
if(response.data.status == 'success')
{
$http({
method: "GET",
url: "http://127.0.0.1:8081/webSiteList"
}).then(function(responseData){
if(responseData.data.status == 'success')
{
$scope.sara = 'testsara';
$scope.websiteData = {id : 'a', name: 'test'}; // responseData.data.data;
console.log('scope website data', $scope.websiteData);
$state.go('account', 'cache: false');
}
});
}
else
{
}
}, function(response) {
console.log('error',response)
});
}
}]);
Let me know if this helps!
EDIT::
SOLUTION 2:
There is another way you can accomplish the same just by making a change in your controller code. See below code:
myApp.controller('adminCtrl', ['$scope', '$http', '$state', 'getArticleData', function($scope, $http, $state, getArticleData){
//Initialize your articleList
$scope.articleList = $scope.articleList || {};
$scope.addArticle = function(){
$state.go('addArticle');
}
// get website list
$scope.showArticles = function(){
/*$scope.articleList = 'this is default article scope value';
alert($scope.articleList)
$scope.$applyAsync(function() {
$scope.articleList = "Another value rest"; alert($scope.articleList)
});*/
$http({
method: "GET",
url: "http://127.0.0.1:8081/articleList",
params: {
website:$scope.website
}
}).then(function(responseData){
if(responseData.data.status == 'success')
{
console.log('test dataaa');
console.log(responseData);
alert('page should modified')
alert('This is test');
//Save your data
$scope.articleList = {id:'test', name: 'article list'};//responseData.data.data;
$scope.artLs = "I am testt model";
$state.go('articleList', 'cache: false');
}
})
}
$scope.adminLogin = function(){
var uname = $scope.username;
var pass = $scope.password ;
alert(uname+'--'+pass);
$http({
method : "GET",
url : "http://127.0.0.1:8081/adminLogin",
params: {
username : uname,
pwd: pass
}
}).then(function(response) {
console.log('succes',response);
if(response.data.status == 'success')
{
$http({
method: "GET",
url: "http://127.0.0.1:8081/webSiteList"
}).then(function(responseData){
if(responseData.data.status == 'success')
{
$scope.sara = 'testsara';
$scope.websiteData = {id : 'a', name: 'test'}; // responseData.data.data;
console.log('scope website data', $scope.websiteData);
$state.go('account', 'cache: false');
}
});
}
else
{
}
}, function(response) {
console.log('error',response)
});
}
}]);
is the alert that you have put printing the correct value?
Based on my understanding I think you set the articleList on ng-change called in one view file. After that you change state and go to another view file where you expect to see the updated articleList value which you set in the previous view. But, I think what may be happening is that when you navigate to the second view your controller might be getting reloaded and your $scope.articleList gets reset. Try printing the value of articleList before and after you change view.
To prevent this you can try using angular services to save the articleList value
I am calling a json in controller using service but I am receiving an error saying "TypeError: Cannot read property 'then' of undefined". I tried existing answers but couldn't get it to work.
Controller:
app.controller("myController",["$scope","MyService","$http", function($scope,MyService,$http){
$scope.hi = "hello";
MyService.getMyData().then(function(response){
console.log(response);
});
}]);
Service:
app.service("MyService", ["$http", function($http) {
this.getMyData = function() {
return
$http({
method: 'GET',
url: 'myList.json',
headers: {
'Content-Type': 'application/json'
}
}).then(function successCallback(response) {
console.log(response);
return response;
}, function errorCallback(response) {
console.log(error);
return response;
});
};
}]);
Thank you.
Currently you had just return(on first line) thereafter on next line you returned $http promise. Basically you have return alone it returns nothing/undefined (this is how javascript works) & next statements are getting ignored from this.getMyData function.
You have to have return & $http({ promise to be together in one line, otherwise return will return empty statement.
this.getMyData = function() {
//`return` & `$http` promise should be on same line, otherwise undefined would get return
return $http({
method: 'GET',
url: 'myList.json',
headers: {
'Content-Type': 'application/json'
}
}).then(function successCallback(response) {
console.log(response);
return response;
}, function errorCallback(response) {
console.log(error);
return response;
});
};
#pankajparker is absolutely correct.
Implemented a codepen for kicks and adjusted to use Angular 1.5's components. Here's the link:
http://codepen.io/Lethargicgeek/pen/YWryoE
(function() {
angular.module("myApp", []);
angular.module("myApp").component('myCmp', {
controller: ctrlFn,
templateUrl: "myCmp.tpl.html"
});
ctrlFn.$inject = ["myService"];
function ctrlFn(myService) {
var $ctrl = this;
// BINDINGS
$ctrl.hi = "hello";
$ctrl.getData = getData;
$ctrl.data = null;
$ctrl.myService = myService; // Binding so that we can easily see results
// END BINDINGS
// FUNCTION
function getData() {
var returnedPrms = myService.getMyData();
returnedPrms.then(function(response) {
$ctrl.data = response;
});
}
// END FUNCTIONS
}
angular.module("myApp").service("myService", svcFn);
svcFn.$inject = ["$http"];
function svcFn($http) {
var svc = this;
//BINDINGS
svc.getMyData = getMyData;
//END BINDINGS
function getMyData() {
var firstPrms = $http.get("http://codepen.io/anon/pen/LVEwdw.js"); // Random bit of json pulled from internets
var secondPrms = firstPrms.then(function success(response) {
svc.successResp = response;
return response;
}, function error(response) {
svc.errorResp = response;
return response;
});
return secondPrms;
}
}
})(); // end iife
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
<div ng-app="myApp">
<script type="text/ng-template" id="myCmp.tpl.html">
<div>
<h1>{{$ctrl.hi}}</h1>
<a class="btn btn-primary" ng-click="$ctrl.getData()">
Trigger $Http Call
</a>
<dl class="dl-horizontal">
<dt>$ctrl.data:</dt>
<dd>{{$ctrl.data}}</dd>
<dt>$ctrl.myService.successResp:</dt>
<dd>{{$ctrl.myService.successResp}}</dd>
<dt>ctrl.myService.errorResp:</dt>
<dd>{{ctrl.myService.errorResp}}</dd>
</dl>
</div>
</script>
<my-cmp></my-cmp>
</div>
.controller('LoginConnect', ['$scope', 'connecting',
function(connecting, $scope){
$scope.user = {};
var inputLogin = $scope.user.login;
var inputPassword = $scope.user.password;
$scope.connect = function (){
connecting(ConnectingFactory);
};
}
])
.factory('connecting', ['$http','$q', function ($http,$q,inputLogin, inputPassword, ConnectingFactory){
var ConnectingFactory = {};
console.log(ConnectingFactory);
ConnectingFactory.login = function(){
var deferred = $q.defer();
$http({
method: 'POST',
url: "http://api.tiime-ae.fr/0.1/request/login.php",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {login: inputLogin, password: inputPassword}
})
.success(function(result){
deferred.resolve(result);
var promise = deferred.promise;
promise.then(function(result){
console.log(result);
// jsonTab = angular.fromJson(result);
// $scope.result = result["data"];
// $scope.user.token = result["data"];
});
})
};
return ConnectingFactory;
}]);
;
And here the HTML :
<!-- User Connection -->
<form name="userConnect" ng-submit="connect()" novalidate ng-controller="LoginConnect">
<label>
Enter your name:
<input type="text"
name="myEmail"
ng-model="user.login"
/>
</label>
<label>
Enter your Password:
<input type="password"
name="password"
ng-model="user.password"
/>
</label>
<input type="submit" value="Connection">
<p>resultat : {{result}}</p>
<p ng-model="user.token">
token : {{mytoken}}
</p>
<p ng-model="user.datab">
datas : {{datab}}
</p>
<br><br><br>
</form>
Hi, I m new in Angular Js developpement, i have no error but not any data in sent to the API. I think their is no link between my function "connect()" and the factory. Could you help me pls ?
Don't use the success method either way.Both methods have been deprecated.
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead. If
$httpProvider.useLegacyPromiseExtensions is set to false then these
methods will throw $http/legacy error.
Here is the shortcut method
$http.post('/someUrl', data, config).then(successCallback, errorCallback);
Here is a longer GET method sample
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Official Documentation
Regarding the factory , call it correctly as ConnectingFactory.login().
Also, the order here is incorrect, as pointed out by Harry.
['$scope', 'connecting',
function(connecting, $scope){
.controller('LoginConnect', ['$scope', 'connecting',
function($scope, connecting){
$scope.user = {};
$scope.connect = function(){
connecting();
};
}
])
.factory("connecting", ["$scope", "$q", "$http", function ($scope,$q, $http){ var deferred = $q.defer();
$http({
method: 'POST',
url: "http://api.tiime-ae.fr/0.1/request/login.php",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {login: $scope.user.login, password: $scope.user.password}
})
.success(function(result){
deferred.resolve(result);
var promise = deferred.promise;
promise.then(function(result){
jsonTab = angular.fromJson(result);
$scope.result = result["data"];
$scope.user.token = result["data"];
});
})
}])
;
and here the HTML:
<!-- User Connection -->
<form name="userConnect" ng-submit="connect()" novalidate ng-controller="LoginConnect">
<label>
Enter your name:
<input type="text"
name="myEmail"
ng-model="user.login"
/>
</label>
<label>
Enter your Password:
<input type="password"
name="password"
ng-model="user.password"
/>
</label>
<input type="submit" value="Connection">
<p>resultat : {{result}}</p>
<p ng-model="user.token">
token : {{mytoken}}
</p>
<p ng-model="user.datab">
datas : {{datab}}
</p>
<br><br><br>
</form>
Hi, I am new in Angular JS, could you help me pls to fixe this. I have the following error :$scopeProvider <- $scope <- connecting
I think this error is due to the link betwwen controller and factory
Your service needs to return something.
instead try:
.factory("connecting", ["$scope", "$q", "$http", function connect($scope,$q, $http){
return function() {
//your method
};
}])
Here is the code Example of linking controller and factory similar to yours. You simply return the something from the factory.
.controller('LoginConnect', ['$scope', 'connecting',
function($scope, connecting) {
$scope.user = {};
$scope.connect = function() {
connecting.login($scope.signupData.username, $scope.signupData.password).success(function(data) {
//
$sessionStorage.userid = data.UserId;
$sessionStorage.token = data.access_token;
if (data.UserId != "") {
$state.go('app.editProfile');
}
})
.error(function(data, status, headers, config) {
console.log("http error", data);
});
};
}
])
.factory('connecting', ["$scope", "$q", "$http", function ($scope,$q, $http){
var urlBase = 'http://apple.com:7071';
//Login
return {
login: function(loginusername, loginpassword) {
return $http({
method: 'POST',
url: urlBase + '/Login',
data: {
username: loginusername,
password: loginpassword,
grant_type: 'password'
},
transformRequest: function(obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
})
}
}
}])
Fatcory needs to return an Object.
.factory("connecting", ["$scope", "$q", "$http", function ($scope,$q, $http){
var ConnectingFactory = {};
ConnectingFactory.login = function(){
var deferred = $q.defer();
$http({
method: 'POST',
url: "http://api.tiime-ae.fr/0.1/request/login.php",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {login: $scope.user.login, password: $scope.user.password}
})
.success(function(result){
deferred.resolve(result);
var promise = deferred.promise;
promise.then(function(result){
jsonTab = angular.fromJson(result);
$scope.result = result["data"];
$scope.user.token = result["data"];
});
})
};
return ConnectingFactory;
}]);
I've been trying to implement this easy feature in Angular, but without no success.
I have two controllers and one service. The service provides a shared methods to retrieve if user is logged in or not;
app.factory("shared",["$rootScope",function($rootScope){
var data = {};
data.val = false;
data.get = function() {
return data.val;
},
data.set = function(val) {
data.val = val;
};
return data;
}]);
Then I have a controller attached to login/logout bar where login and logout links should be changed with the help of ng-show and ng-hide. Here is a html code for this:
<ul class="reg" ng-controller="mainCntr">
<li ng-hide="shared.get()"> Signup </li>
<li ng-hide="shared.get()">Login</li>
<li ng-show="shared.get()">Logout</li>
</ul>
And mainCntr attached to this:
app.controller("mainCntr,["$scope","shared","$rootScope",function($scope,shared, $rootScope){
$scope.$watch("shared.get()",function(newval){
console.log(newval);
},true);
}]);
And lastly, I have login controller for login form rendered into when we are on /login page. I should notice that the above HTML for login/signup links is always on index.html page. So, loginCntr is below:
app.controller("loginCntr",["$scope","$http", "$window","$rootScope", "$location","shared",function($scope,$http, $window, $rootScope,$location,shared){
$scope.login = "";
$scope.password = "";
$scope.response = "";
$scope.loggedin = false;
$scope.submit = function(isValid) {
if (isValid) {
$http({
method: "POST",
url: "/authenticate",
data: $.param({login:$scope.login,password:$scope.password}),
headers: {"Content-Type": "application/x-www-form-urlencoded"}
}).success(function(data,status,headers,config){
$window.sessionStorage.token = data.token;
console.log($window.sessionStorage.token);
$scope.response = "You logged in successfully";
shared.set(true); /////// Here I set shared valued to true when the user is logged
}).error(function(data,status,error,config){
delete $window.sessionStorage.token;
$scope.response = data.response;
});
};
};
}]);
So, that's it, but it doesn't work. Being new to Angular, it is hard time for me to figure out what is wrong. May be it's because "shared" value is set in asynchronyous callback and thus never read, because the login section has been already loaded?
why you not try $emit event listener.
like :
///****mainCntr
app.controller("mainCntr,["$scope","shared","$rootScope",function($scope,shared, $rootScope){
$scope.$on("loginEvent", function($event, args){
alert(args.msg);
});//Listen $emit Event
}]);
///****loginCntr
app.controller("loginCntr",["$scope","$http", "$window","$rootScope", "$location","shared",function($scope,$http, $window, $rootScope,$location,shared){
$scope.login = "";
$scope.password = "";
$scope.response = "";
$scope.loggedin = false;
$scope.submit = function(isValid) {
if (isValid) {
$http({
method: "POST",
url: "/authenticate",
data: $.param({login:$scope.login,password:$scope.password}),
headers: {"Content-Type": "application/x-www-form-urlencoded"}
}).success(function(data,status,headers,config){
$window.sessionStorage.token = data.token;
console.log($window.sessionStorage.token);
$scope.response = "You logged in successfully";
$scope.$emit("loginEvent", {msg : "Login Successful..."}) /////// Emit an event
}).error(function(data,status,error,config){
delete $window.sessionStorage.token;
$scope.response = data.response;
});
};
};
}]);