I am trying to load a number of elements in a div from json via $http call. But whatever I try the list remains empty. Here is the code.
<div class="submenu" >
<div class="menuitem" ng-repeat="item in navigator" >{{item}}
{{item.label}}
</div>
It is an abstract state and I have assigned controller greetingctrl to it in routes. The JS code is
app.controller('greetingCtrl',function($scope,$cookieStore,$timeout,$state,msg,SERVICE,RestService,$stateParams){
$scope.list = [];
$scope.navigator;
$scope.options.loading = false;
var currentmsg;
$scope.user = $cookieStore.get('userinfo');
$scope.init = function(){
var url = SERVICE.greetingMsg;
var data = {
providerID : $cookieStore.get('userinfo').providerId,
loginID : $cookieStore.get('userinfo').loginId,
action : "GET_MESSAGE"
}
RestService.post(url,data).then(function(res){
$scope.navigator = res.messages;
},
function(err){
console.log(err);
});
}
Here I can successfully receive the data but the data in the list never comes. RestService.post is $http method I have defined in a service.I am using angular 1.5.8 and I am new to angular.
EDIT: Removed ng-show and ng-if. Still the data is nnot showing
You need to check two variables:
- showmenu I don't see its value changing at all so it's always false.
- loadingisDone same as the previous.
And remember to call $scope.init somewhere.
what is the ng-if tag contains, it should have some conditions to check
change to
0'>
Try if it works
You dont need to use ng-if and ng-show both directives on same tag.
You can use either one to display that DIV by using && and || operators.
Please check the if the value of variables are updating properly.
For async execution use $scope.$apply to update your scoped data.
RestService.post(url,data).then(function(res){
$scope.$apply(function() {
$scope.navigator = res.messages;
});
}
Related
i am trying to bind value in label when i get signal in session.
for first it shows values in label but when i send signal second time it shows blank label and is not updating value.
code i am using
HTML
<div class="modal-content">
<h4>Incoming Call From...</h4>
<label class="alignCenter incomingReason">{{requestedCall.reason}}</label>
<label class="alignCenter">{{requestedCall.hname}}</label>
</div>
Controller
session.on("signal:chat", function (event) {
var data = JSON.parse(event.data);
$scope.requestedCall.reason = data.complain_name;
$scope.requestedCall.hname = data.username;
$scope.PlayRingtone();
$scope.$apply();
$scope.showModel();
});
when i send signal , i gets data in var data = JSON.parse(event.data);
i always have to use $scope.$apply() other wise it doesn't bind value for first time also but for second time it doesn't work at all.
i have tried $timeout , $digest but nothing works at all , any help would be appreciated.
When we are out of angular, things doesn't work. So if you are doing something in jQuery or any other library angular will not know what has been changed. For that you've to tell angular explicitly by using $apply or $digest
$scope.$apply(function () {
$scope.requestedCall.reason = data.complain_name;
$scope.requestedCall.hname = data.username;
$scope.PlayRingtone();
$scope.showModel();
});
Let me know if it works!
I have an ng-repeat with an ng-show inside. The variable passed to ng-show is not fully initiated until a promise in my controller resolves.
This is causing the ng-show to always end up reading a "falsey" object because it is reading the value before the promise finishes getting the correct results from the service.
Is there a way to cause the ng-show to wait until my objects are fully initialized?
You could use a control variable, like $scope.loaded = false and make your promise set it to true. Then you can use both conditions in your ng-show.
On the page load set a flag value.
app.controller({.......
$scope.flagPromiseWait = false;
.........
.........
var onSuccess = function (result){
.............
............
$scope.flagPromiseWait = true;
},
var onError = function(err){
............
}
});
and on HTML use
<div ng-show="$scope.flagPromiseWait">...........<div>
HTML:
<div class="span10" ng-controller="GroupFieldsCntl" ng-init="init()">
<div ng-repeat="field in fields"></div>
</div>
GroupFieldCntl:
function GroupFieldsCntl($scope) {
$scope.fields = [];
$scope.init = function() {
// Get fields.
$.get(ctx + 'admin/fields/fieldsJSON', function(data) {
for(var i in data) {
$scope.fields.push(data[i]);
}
});
}
}
I'm sure the ajax call get correct response, but the html page doesn't display those data.
Like the commentors here say:
1. Use $http.get instead of $.get. This is Angular's Ajax and you should be using it. [it needs to be injectecd into the controller]
2. If you loop in var i in data you might loop through methods of non-data properties, so as was suggested, use
for (var i in data) {
if data.hasOwnProperty(i)
//do something
}
}
And if you don't think there will be issues with bad data, you can always use the following syntax to have the resolved promise (get request) resolve itself to the $scope variable:
$scope.fields = $http.get(tx + 'admin/fields/fieldsJSON');
When the data arrives fields will automatically contain the JSON response after it was resolved. This is a shortcut which doesn't handle error responses though.
The changes done to data will trigger view changes only if you do it with angular functions or use $apply on other functions. So as the comments suggest you can (should) either use angular's $http service, or call your function inside $apply.
I'm just starting to play with angularJS, so maybe I'm asking something easy to do, but I can't find the way to do it.
The situation is the following: I have a list that's populated by an ng-repeat taking the values from a scoped controller variable. This variable is loaded on page load by an jsonp call, and this works fine.
The problem comes when I need to reload this list based on another select. For example, if a select 'day' value in the select I need to show some values and when I select 'week' I need to show others (also loaded via ajax).
What I've tried is to have a service that loads the data and returns it, and in the controller have two methods, one for the first load and another for the second one that does $scope.apply with the variable. I then call this second method on select value change (I've done it with jquery to simplify it until I can fix this).
This is part of my HTML
<div x-ng-controller='LeaderboardCtrl'>
<select id='leaderboard-select'>
<option value='day'>day</option>
<option value='week'>week</option>
<option value='month'>month</option>
</select>
<div x-ng-repeat='p in leaderboard'>
<p>{{p}}</p>
</div>
</div>
And this is part of the code that affects this functionality
var lead = angular.module("lead",[]);
function LeaderboardCtrl($scope,$attrs,$http,jtlanService) {
$scope.leaderboard = [];
$scope.period = 'day';
var data = {
period:$scope.period
};
$scope.loadLeaderboard = function(){
myService.loadLeaderboard(data).then(function(leaderboard) {
$scope.leaderboard = [];
$scope.leaderboard.push.apply($scope.leaderboard,leaderboard);
});
}
$scope.reloadLeaderboard = function() {
myService.loadLeaderboard(data).then(function(leaderboard) {
$scope.$apply(function() {
$scope.leaderboard = [];
$scope.leaderboard.push.apply($scope.leaderboard,leaderboard);
});
});
}
$scope.loadLeaderboard()
}
lead.service("myService",["$http", function($http) {
var myService = {
loadLeaderboard : function(data) {
var promise = $http.jsonp("/widget/leaderboardJSONP?callback=JSON_CALLBACK&_="+new Date(),{
params:data,
cache:false,
ajaxOptions: { cache: false }
}).then(function(response) {
return response.data;
});
return promise;
}
};
return myService;
}]);
$("#leaderboard-select").change(function(){
scope.period = $("#leaderboard-select").val();
scope.reloadLeaderboard();
});
Here's a fiddle with the code: http://jsfiddle.net/WFGqN/3/
Your fiddle is riddled with issues:
There's no ng-app in your mark-up
You need to change the second Framework Extensions dropdown to one of the "No wrap" options
Your service needs to be defined above your controller
Your controller is referencing "jtlanService" but you've defined "myService"
Your $http.jsonp call isn't going to work as is, but you could use can use the echo service (see Ajax Requests on the left side) to emulate requests
You can't and shouldn't be using jQuery events to call Angular controllers. You should use ng-change and not $().change (and even if you were using jQuery for event binding, you should be using $().on('change')).
You didn't need to use $scope.$apply in your loadLeaderboard function, since when you're calling it, you were already inside of of an $apply call.
There's no need for 2 load+reload leaderboard methods.
And after all that, you don't actually need jQuery.
Here's a fiddle that fixes things up and I think gets you what you want: http://jsfiddle.net/WFGqN/5/. You'll of course need to fix the service on your end, but you get the idea.
I recommend reading this SO answer: "Thinking in AngularJS" if I have a jQuery background?
I'm running into a problem with AngularJS where I use a callback on a custom service in order to pass data from one controller to another.
In particular, I'm trying to create a very simple logging service in which one controller registers a listener function with the service to receive updates when a message is logged, and the other controller logs a message when a button in the UI is clicked (triggering the listener in the first controller).
The listener function then updates a $scope.messages variable to show the newly logged message in the UI. However, while the newly arrived message arrives in the listener function, the UI is not updated.
I believe this is because AngularJS is not aware that $scope.messages is being updated.
However, trying to wrap the update of $scope.messages with $scope.$apply has brought no avail ($apply already in progress).
HTML Code:
<div ng-app="myApp">
<div ng-controller="ButtonCtrl">
<button type="button" ng-click="logMessage()">Button</button>
</div>
<div id="console" ng-controller="ConsoleCtrl">
<div ng-repeat="consoleItem in messages">{{consoleItem.message}}</div>
</div>
</div>
Javascript Code:
var module = angular.module('myApp', []);
module.factory('MyConsole', function($rootScope) {
var listeners = [];
var myConsoleService = {};
myConsoleService.log = function(messageObj) {
angular.forEach(listeners, function(listener){
listener(messageObj);
});
};
myConsoleService.registerListener = function(listener) {
listeners.push(listener);
};
return myConsoleService;
});
function ConsoleCtrl($scope, MyConsole){
$scope.messages = [{"message":"First message!"}];
MyConsole.registerListener( function(msgObj){
// while this console.log call below works as expected, the $scope.messages.unshift call does not update the view
$scope.messages.unshift(msgObj.message);
console.log($scope.messages);
});
}
function ButtonCtrl($scope, MyConsole) {
$scope.logMessage = function () {
MyConsole.log({message:"myLogmessage"});
};
}
Code can also be found for your convenience on JSFiddle: http://jsfiddle.net/G5LAY/3/
Any help would be greatly appreciated :-)
Thanks!
Your code is working, it's just that this line: $scope.messages.unshift(msgObj.message); only adds the message string to $scope.messages when your template expects $scope.messages to be a list of objects instead. So changing it to $scope.messages.unshift(msgObj); should do the trick.