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;
});
}
So I have a controller with a couple of asynchronous .then functions. In the end I catch them all with a $q.all() function to continue my synchronous work. Now I have a select with dynamic options:
<select ng-model="data.selectedUser" ng-change="changeList()" ng-options="user as user.firstname + ' ' + user.lastname for user in users">
<option value="">Select a user...</option>
</select>
With ng-change I want to get the selected user in my controller, so I call changeList(). In the changeList function I do some simple alerts which do not trigger. When I do the test alert first in the controller it even freezes at choosing an option.
In my $q.all() function:
$q.all(promises).then(function () {
users = UserService.getUsers();
$scope.users = users;
$scope.data.selectedUser = {};
$scope.changeList = function () {
var chosenUser = $scope.data.selectedUser;
alert(chosenUser.firstname);
alert('test');
};
}, function () {
alert('Failed');
});
The alerts do nothing, I also tried putting the changeList function out of the $q.all function in the bottom of the controller. What am I doing wrong?
EDIT:
user is already defined and all of that is working. It is purely about why the ng-change is not working. It is also tested without emptying the selectedUser scope first.
The it does not look like ng-change works on a select. You can have a look at this js-fiddle: http://jsfiddle.net/fc984j9b/
Instead of using the ng-change to fire the event I used a $watch on the ng-model of the select to trigger a function instead, in your case it would be:
$scope.$watch("data.selectedUser", function(){
$scope.changeList();
});
I hope hat helps
Best Regards
Oliver
Here is a JSFiddle that uses your code and does work:
http://jsfiddle.net/A_Sambres/2kwhw0dw/1/
The things there that must be different from your code are the users object
users = [{"firstname":"Adrien","lastname":"Foo"}, ...{"firstname":"Thing2","lastname":"Foo"}];
, and the initialization of the data object.
$scope.data = {selectedUser : {}};
So I guess you could inspect the differences between this code and yours to spot what goes wrong.
It may be the users object that has not the right structure, or the $scope.data that is not correctly declared in the controller.
I need to change the order of scope, save but me back an error that save() is not a function.
I'm using restangular to create the objects.
The function is triggered Onsort, I tried using http, but also gives me error.
$scope.onChange = function() {
ApiRestangular.all($scope.section).getList($scope.query).then(function(res){
$scope.items = res;
order = ApiRestangular.copy(res);
console.log(order);
$scope.sortOptions = {
animation : 150,
onSort: function(){
order.put().then(function(){
toast.msgToast($scope.section+ ' ...Ordem atualizada!');
});
}
};
});
};
There are a few issues here but I think the biggest one is that "save()" really isn't a function. I believe the correct syntax is $save().
Here is the documentation.
https://docs.angularjs.org/api/ngResource/service/$resource
Without seeing the rest of your controller code it is tough to say what other problems there may be (dependency injection?). But this should get your started.
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.
Currently I have an Angular.js page that allows searching and displays results. User clicks on a search result, then clicks back button. I want the search results to be displayed again but I can't work out how to trigger the search to execute. Here's the detail:
My Angular.js page is a search page, with a search field and a search
button. The user can manually type in a query and press a button and
and ajax query is fired and the results are displayed. I update the URL with the search term. That all works fine.
User clicks on a result of the search and is taken to a different page - that works fine too.
User clicks back button, and goes back to my angular search page, and the correct URL is displayed, including the search term. All works fine.
I have bound the search field value to the search term in the URL, so it contains the expected search term. All works fine.
How do I get the search function to execute again without the user having to press the "search button"? If it was jquery then I would execute a function in the documentready function. I can't see the Angular.js equivalent.
On the one hand as #Mark-Rajcok said you can just get away with private inner function:
// at the bottom of your controller
var init = function () {
// check if there is query in url
// and fire search in case its value is not empty
};
// and fire it after definition
init();
Also you can take a look at ng-init directive. Implementation will be much like:
// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>
// in controller
$scope.init = function () {
// check if there is query in url
// and fire search in case its value is not empty
};
But take care about it as angular documentation implies (since v1.2) to NOT use ng-init for that. However imo it depends on architecture of your app.
I used ng-init when I wanted to pass a value from back-end into angular app:
<div data-ng-controller="myCtrl" data-ng-init="init('%some_backend_value%')"></div>
Try this?
$scope.$on('$viewContentLoaded', function() {
//call it here
});
I could never get $viewContentLoaded to work for me, and ng-init should really only be used in an ng-repeat (according to the documentation), and also calling a function directly in a controller can cause errors if the code relies on an element that hasn't been defined yet.
This is what I do and it works for me:
$scope.$on('$routeChangeSuccess', function () {
// do something
});
Unless you're using ui-router. Then it's:
$scope.$on('$stateChangeSuccess', function () {
// do something
});
angular.element(document).ready(function () {
// your code here
});
Dimitri's/Mark's solution didn't work for me but using the $timeout function seems to work well to ensure your code only runs after the markup is rendered.
# Your controller, including $timeout
var $scope.init = function(){
//your code
}
$timeout($scope.init)
Hope it helps.
You can do this if you want to watch the viewContentLoaded DOM object to change and then do something. using $scope.$on works too but differently especially when you have one page mode on your routing.
$scope.$watch('$viewContentLoaded', function(){
// do something
});
You can use angular's $window object:
$window.onload = function(e) {
//your magic here
}
Another alternative:
var myInit = function () {
//...
};
angular.element(document).ready(myInit);
(via https://stackoverflow.com/a/30258904/148412)
Yet another alternative if you have a controller just specific to that page:
(function(){
//code to run
}());
When using $routeProvider you can resolve on .state and bootstrap your service. This is to say, you are going to load Controller and View, only after resolve your Service:
ui-routes
.state('nn', {
url: "/nn",
templateUrl: "views/home/n.html",
controller: 'nnCtrl',
resolve: {
initialised: function (ourBootstrapService, $q) {
var deferred = $q.defer();
ourBootstrapService.init().then(function(initialised) {
deferred.resolve(initialised);
});
return deferred.promise;
}
}
})
Service
function ourBootstrapService() {
function init(){
// this is what we need
}
}
Found Dmitry Evseev answer quite useful.
Case 1 : Using angularJs alone:
To execute a method on page load, you can use ng-init in the view and declare init method in controller, having said that use of heavier function is not recommended, as per the angular Docs on ng-init:
This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit, such as for aliasing special properties of ngRepeat, as seen in the demo below; and for injecting data via server side scripting. Besides these few cases, you should use controllers rather than ngInit to initialize values on a scope.
HTML:
<div ng-controller="searchController()">
<!-- renaming view code here, including the search box and the buttons -->
</div>
Controller:
app.controller('SearchCtrl', function(){
var doSearch = function(keyword){
//Search code here
}
doSearch($routeParams.searchKeyword);
})
Warning : Do not use this controller for another view meant for a different intention as it will cause the search method be executed there too.
Case 2 : Using Ionic:
The above code will work, just make sure the view cache is disabled in the route.js as:
route.js
.state('app', {
url : '/search',
cache : false, //disable caching of the view here
templateUrl : 'templates/search.html' ,
controller : 'SearchCtrl'
})
Hope this helps
I had the same problem and only this solution worked for me (it runs a function after a complete DOM has been loaded). I use this for scroll to anchor after page has been loaded:
angular.element(window.document.body).ready(function () {
// Your function that runs after all DOM is loaded
});
You can save the search results in a common service which can use from anywhere and doesn't clear when navigate to another page, and then you can set the search results with the saved data for the click of back button
function search(searchTerm) {
// retrieve the data here;
RetrievedData = CallService();
CommonFunctionalityService.saveSerachResults(RetrievedData);
}
For your backbutton
function Backbutton() {
RetrievedData = CommonFunctionalityService.retrieveResults();
}
call initial methods inside self initialize function.
(function initController() {
// do your initialize here
})();