How to wait for response from service in ng-repeat - angularjs

I am trying to display the items using ng-repeat and when the list is initailly loading , trying to call another service to get the details about the first item.
Here is my code:
<div ng-repeat="item in itemList">
<div ng-click="setCurrentItem(item,$index)" ng-init="initCurrentItem(item,$index)">
item.id
</div>
</div>
In controller:
function init(){
itemService.loadItem();
}
$scope.itemList = function(){
return itemService.getItemsList();
}
from this service I am getting the following data :
itemName:x001,
item.id:10
itemName:x002,
item.id:20,
itemName:x003,
item.id:30.
I am calling another service to get itemDetails.
$scope.currentItemDetails ={};
$scope.currentItemDetails.id ='';
$scope.initCurrentItem(item.index){
if(scope.currentItemDetails.id === ''){
$scope.setCurrentItem(item.index);
}
}
$scope.setCurrentItem = function(item,index){
item.index = index;
itemService.loadItemDetails(item.id).then(function(response){
if(angular.isDefined(response)){
$scope.currentItemDetails = response.data;
}
});
when the list loading initailly and calling initCurrentItem, the currentItemDetails holding last item (itemName:x003,id:30). ng-repeat is repeat the values without waiting response from the service. How do I wait in the loop until I get response from first item?

Just use the same logic in init method as you have in the other example - with .then( etc. And assign value to the repeating variable itemList. Then table HTML will be refreshed automagically when the data arrives and Promise will be resolved:
<div ng-repeat="item in itemList">
function init(){
itemService.loadItem().then(function(response){
if(angular.isDefined(response)){
$scope.itemList = response.data;
}
});
}
UPD
try calling initCurrentItem after the data is loaded
function init(){
itemService.loadItem().then(function(response){
if(angular.isDefined(response)){
$scope.itemList = response.data;
//here we iterate received array $scope.itemList and call initCurrentItem on each of them
$scope.itemList.forEach(function(item, i){
$scope.initCurrentItem(item, i);
});
}
});
}

Related

angulajs data on the page is not loading after route redirection

when I am at the home page and click on the link in the navigation bar
<li class="nav-item" ng-show="currentUser">
<a class="nav-link" ng-show="currentUser"
ng-href="#/pictures"">Pictures</a>
</li>
It goes to the page, I can see the data is downloaded but it is not shown in the UI when update $scope.urlListUI.
urlListInRoomUnits=loadPicture(filePathInRoomUnitPicture);
$scope.urlListUI=urlListInRoomUnits;
$scope.$apply();
console.log('update ui: '+urlListInRoomUnits);
however, if I refresh the page, it will work.
the UI code
<div ng-repeat = "urlRecord in urlListUI">
<p>{{urlRecord[1]}}</p>
<img ngf-src="urlRecord[0]" class="img-thumbnail">
</div>
the function: loadPicture(filePathInRoomUnitPicture)
function loadPicture(pictureTypeFolder){
console.log('loadpicture is running, input parameter:'+pictureTypeFolder);
var urlList=[];
$scope.whereThePictureIs=pictureTypeFolder;
//list image from firebase storage
var storageRefDownloadByPictureType = storageRef.child('airconPicture').child(pictureTypeFolder);
storageRefDownloadByPictureType.listAll()
.then(function(result) {
console.dir(result);
result.items.forEach(function(imageRef) {
// And finally display them
imageRef.getDownloadURL()
.then(function(url){
// TODO: Display the image on the UI
urlList.push([url,imageRef.name]);
})
.catch(function(error) {
// Handle any errors
});
});// end of for each download
})// end of list all promise
.catch(function(error) {
// Handle any errors
});
return urlList;
};// end of load Pciture by type
thanks for helping or direct me to the right source.
So what I see, first, you try to resolve storageRefDownloadByPictureType.listAll()
After resolving (let's say 1 sec), you run in a loop on results and try to resolve a list of items:
result.items.forEach(function(imageRef) {
imageRef.getDownloadURL().then(function(url){
})
You resolve all at once, let's say, another 1 sec.
Your method does not return promise but empty urlList because you populate it in the next 2 seconds.
So instead urlListInRoomUnits=loadPicture(filePathInRoomUnitPicture);
It should be something like (you can write loadPicture in some service, lets say MyService):
MyService.loadPicture(filePathInRoomUnitPicture).then(function (urls) {
//here you get all your results
$scope.urlListUI = //...
});
and now loadPicture in MyService:
this.loadPicture = function(filePathInRoomUnitPicture){
//...
return storageRefDownloadByPictureType.listAll().then(function(result) {
// create list of promises:
var promises = [];
result.items.forEach(function(imageRef) {
promises.push(imageRef.getDownloadURL());
})
// chain promises
return $q.all(promises);
};

populating data from multiple async sources in angularjs and merging in an object

I'm new to angularJS and the whole concept of deferred/promises so this might not be the cleanest of the codes but want to know what am i doing wrong here.
Basically in factory in my first async call I'm fetching data(stockname and quantity) from Firebase then
in my second async call I'm trying to get additional details like current price using $http. While i successfully get the details I'm unable to merge it in an object in my controller and show it as a table using ng-repeat.
//below is my Factory snippet
factory.getStocks = function(){
var promise = firebase.database().ref().child("Stock").once('value');
var qpromise = $q.when(promise).then(callback)
return stock;
};
function callback(snapshot){
var i=0;
snapshot.forEach(function(child)
{
stocks[i] = {
name: child.key,
holding: child.val(),
price: -1,
value: -1
};
i = i+1;
});
return stocks;
}
Controller as below: but get an error "Unable to get property '0' of undefined or null reference" I'm assuming since the stocks might not be populated yet. Is there a better way to populate the price
portfolio.controller('updatePortfolio', function($scope,stockFactory,$http){
init();
function init()
{
$scope.stocks = stockFactory.getStocks();
}
}
function updatePrice()
{
$http.get('//call for api')
.then(function(response))
{
$scope.stocks[0].price = response.data; //error "Unable to get property '0' of undefined or null reference"
}
// similar call to update rest of the stocks... planning to do it using $q.all if i can somehow figure how to merge this.
}
});
front end:
<table>
<tr>
<th>Stock</th><th>Price</th><th>Holding</th><th>Value</th>
</tr>
<tr data-ng-repeat="s in stocks">
<td>{{s.name}}</td>
<td>{{s.price}}</td>
<td>{{s.holding}}</td>
<td>{{s.price * s.holding}}</td>
</tr>
You're returning an undefined object in your factory method. Return the promise of stocks instead.
factory.getStocks = function(){
var promise = firebase.database().ref().child("Stock").once('value');
return promise.then(callback) //returns stocks
};
And in your controller
portfolio.controller('updatePortfolio', function($scope,stockFactory,$http){
init();
function init() {
//set your scope variables inside the promise success handler
stockFactory.getStocks().then(function(stocks) {
$scope.stocks = stocks;
}).then(function(){
$http.get(api call).then(function(response) {
$scope.stock[0].price = response.data;
});
}
});

After make ajax-post request the html elements are not refresh in angular

I have a issue.i make ajax-post request then it execute properly then i get the response.After process the response i need again make ajax-get then those data i set to a variables in the scope.the data are successfully assign in to variable but html elements are not refresh.this is the sample code.
this is html part
<div ng-controller="AppManagerCtrl" >
<md-list-item ng-repeat="app in apps">
<div>
<div flex="20" layout-padding>
<p>{{app.appId}}</p>
</div>
<div flex="20" layout-padding>
<p>{{app.appName}}</p>
</div>
</md-list-item>
</div>
this the angular service
app.service('AppManagerService',function($http){
this.loadApps = function(){
var request = $http.get('apps');
return request.then(handleSuccess,handleError);
};
this.submitApp = function(){
var request = $http.post('apps',
$('#newAppDetail').serialize(),
{headers: {'Content-Type': 'application/x-www-form-urlencoded'}}
);
return request;
};
function handleError(responce){
console.log(responce);
}
function handleSuccess( response ) {
return response.data.value;
}
});
this the angular controller
app.controller('AppManagerCtrl', function($scope,$mdDialog,$mdMedia,AppManagerService) {
function loadApps(){
AppManagerService.loadApps().then(function(apps){
$scope.apps = apps;
console.log($scope.apps);
}
);
}
loadApps();
$scope.submitNewApp = function(){
AppManagerService.submitApp().then(function(responce){
var data = responce.data;
if(data.status == 1){
loadApps();
}
});
};
});
all these are in the html body.from the begin html part then angular service and finally controller.
The result of an ajax call isn't monitored by Angular, which is why your scope isn't updated (it will be on the digest though).
To solve this, you must manually call $scope.apply().
However, if another digest is already in progress, it will throw an error. So it's safer to use the $timeout utility:
function loadApps(){
AppManagerService.loadApps().then(function(apps){
$timeout(function() {
// update your scope variables here. The refresh will occur automatically.
$scope.apps = apps;
console.log($scope.apps);
});
});
}

how to get data by using ID in angular js?

I am trying to use angular-resource.js file in my demo .I am retrieving
data from json file using $resource and display my data using ng-repeat .But Each item I added one button (info text button).I need to get it infomation using $resource property.I am sending ID on click function .but when I am using $resource property it gives error to me
$scope.getIn=function(id){
// alert(id)
$scope.oneUser = Entry.get({user: id});
console.log($scope.oneUser)
}
here is my code
http://plnkr.co/edit/lB11oQkQjbILK36u8V25?p=preview
If i understand correctly what you are trying to achieve this should solve it:
angular.module('app',['ngResource']).controller('a',function($scope, GetData){
// read data from factory and store it in $scope.posts
GetData.then(
function successCallback(data) {
$scope.posts = data.data;
},
function errorCallback(response) {
console.log(response); // handle any errors
});
// buttonclick to return the values from the selected id
$scope.getIn = function(id){
angular.forEach($scope.posts, function(value) {
if(value.id === id)
{
$scope.selectedValue = value;
}
})
};
console.log($scope.posts)
})
.factory('GetData', function($http){ // use http to read the json
return $http.get('data.json');
});
And the html:
<body ng-app='app' ng-controller='a'>
<div ng-repeat='p in posts'>
<span>{{p.name}}</span>
<button ng-click=getIn(p.id)>info</button>
</div>
{{selectedValue}}
</body>

AngularJS "then" sets up object but object is not accessible on Partial View

Folks,
I have following Button Click which calls AngularJS $scope.getCustomerById method
<div><button type="button" ng-click="getCustomerById(cust.CustomerNumber);">detail of
{{cust.CustomerNumber}} customer</button>
</div>
Now my Controller JS code for getCustomerById is as below
$scope.getCustomerById = function (id) {
CustomerService.getCustomer(id)
.then(function (data) {
$scope.customer = data.data; //which returns data correctly
$location.path('Customer/' + $scope.customer.CustomerNumber.trim());
}, function (error) {
alert(error);
});
};
and it goes to Designated View as well, but this View Does not render customer data. My CustomerView is very simple,
<div data-ng-controller="CustomerController">
{{ customer.CustomerNumber }}//this doesn't show anything, eventhough $scope.customer
//is set in controller as above
</div>
Any help will be really appreciated.

Resources