Angular JS ng-repeat doesn´t showing data correctly - angularjs

I have a strange problem when using ng-repeat.
Only as additional information, I am using ui-router as well.
I did a test with a simple markup that query some data in my local node server and shows with ng-repeat.
To make the test, I click a button to add a new row to server and next, I query the server again to get the new rows updated.
The problem is that the server return correctly all data with the new row added included, but ng-repeat is no showing the rows just added.
Here is more details of the problem.
Firstly, when the page is loaded I have
RowId
1
2
After I click the "Add and Refresh Row" button, I´d expect to have on the screen:
RowId
1
2
5
But I still have only:
RowId
1
2
In console,I checked the return data from my server after I add a row and the data returned is:
{id:1,name:'John Doe'},
{id:2,name:'Mary Doe'}
{id:5,name:'teste'}
where item id=5 is the row just added, buit it doesn´t appears with ng-repeat.
What am I doing wrong?
//markup
<div ng-controller="configClinicaClinicaCtrl">
<a class="btn btn-sm btn-success" ng-click="saveClinica()">Add and Refresh Row</a>
<div>RowId</div>
<div ng-repeat="row in dados track by $index">
{{row.id}}
</div>
</div>
//local server with server.js script at node.js
var clinicas=[
{id:1,name:'John Doe'},
{id:2,name:'Mary Doe'}
];
//get clinicas
app.get('/clinicas', function(req, res) {
res.json(clinicas);
});
//insert clinica
app.post('/clinicas', function(req, res) {
clinicas.push(req.body);
res.json(true);
});
//controller
angular.module("clinang").controller('configClinicaClinicaCtrl',['$scope','$http', '$state', function($scope,$http, $state) {
$scope.dados={};
$scope.clinica={};
var refreshData=function(){
$http.get('/clinicas').then(function(response){
$scope.dados=response.data;
}, function(error){
console.log(error)
});
}
refreshData();
$scope.saveClinica=function(){
$scope.clinica.id=5;
$scope.clinica.nome='teste';
var clinica=$scope.clinica;
$http.post('/clinicas',{clinica}).then(function(response){
refreshData();
}, function(error){
console.log(error)
})
}
}]);

Whenever you do some form of operation outside of AngularJS, such as doing an API call you need to let AngularJS know to update itself. Try this,
var refreshData=function(){
$http.get('/clinicas').then(function(response){
$scope.dados=response.data;
$scope.$apply();
}, function(error){
console.log(error)
});
}

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);
};

How to show JSON data in HTML

I want to show the following JSON in an Angular page :
{"_id":"58b11","name":"Somename","city":"Paris","number":456789123,"__v":0}
I get this data by clicking on a link in an Angular page:
<td ng-click="getData(user._id)">
{{user.name}}
</td>
I am able to get the data from the db and show in the angular page in proper HTML. Now when I click on the link, i get the desired data in JSON on the page http://localhost:8080/api/students/58b11. I want to be able to use Angular {{}} to show the data in proper HTML format.
Angular :
//Created Student factory like this:
app.factory('Student', function($resource) {
var data = $resource('/api/students/:id', { id: '#_id' }, {
update: {
method: 'PUT'
}
});
return data;
});
//controller:
app.controller("dummy2", function($scope, $http, Student, $window){
$scope.getData = function(userID){
$window.location.assign("/api/students/"+userID);
}
)};
NodeJs:
app.use('/api', require('./routes/api'));
Thanks.

How to keep Angular UI responsive during an http get request?

I have a get request in my controller:
$http.get('/api/ideas').success(function(ideas) {
vm.ideas = ideas;
});
As soon as my controller is called, this api is called, and my UI becomes unresponsive until i get the result from the callback / all ideas are listed (with mg-repeat obviously). When i have e.g. 1000 ideas in my database, my UI is unresponsive for 3-5 seconds. But i thought that call was a callback ?!
This is how my backend looks like:
router.get('/api/ideas', controller.find);
exports.find = function(req, res) {
Idea.find(function (err, ideas) {
if(err) { return handleError(res, err); }
return res.json(200, ideas);
});
};
What is the problem here?
EDIT - SOLVED:
When i put a delay in backend like this:
exports.index = function(req, res) {
Idea.find(function (err, ideas) {
if(err) { return handleError(res, err); }
setTimeout(function() {
return res.json(200, ideas);
}, 3000);
});
};
although i just have 2 ideas, the UI is responsive during that 3 seconds. I can still click other parts till i get a response. So i think #Iggy is right. The problem is not the http get, but ng-repeat.
The problem is not the callback here (it's async), the problem is ng-repeat slowing your UI by adding your ideas one by one in the DOM.
To solve this you can use pagination, or look at the different way to improve ng-repeat performance.
A basic way to do so is to use the limitTo filter :
<div ng-init="totalDisplayed=20" ng-repeat="item in items | limitTo:totalDisplayed">
{{item}}
</div>
<button class="btn" ng-click="totalDisplayed = totalDisplayed+20">Load more</button>

Why can't I display data from Mongodb with Angular

and I am trying to display a collection called books in mongodb but for some reason I run into an ng-repeat dupes error. Also the data retrieved from my $http.get operation returns the HTML syntax of the entire page for some reason instead of accessing the data from the books collection. Thing is I created other programs prior to this where I had absolutely no problem with ng-repeat and they still work, the difference being the angular version is older. I am thinking that is the problem. If you have any insight on what I am doing wrong I would appreciate it. Thank you
Error:
Error: [ngRepeat:dupes]
http://errors.angularjs.org/1.3.14/ngRepeat/dupes?p0=book%20in%20library&p1=string%3A%3C&p2=%3C
Controller code:
var app = angular.module("myApp", []);
app.controller("bookCtrl", function($scope, $http) {
var refresh=function(){
$http.get('http://localhost:3000/storeHome').success(function(response){
console.log("I got the data I requested");
console.log(response); //returns HTML of the page instead of an object
$scope.library = response;
$scope.book="";
});
};
refresh();
});
Route code:
var express = require('express');
var router = express.Router();
var Book =require('../../models/book');
router.get('/', function(req, res) {
res.render('bookStore/storeHome');
});
//get all books from the database
router.get('/',function(req,res,next){
Book.find(function(err, books) {
if (err)
res.send(err);
console.log(books);
res.json(books);
});
});
Book model:
var mongoose = require('mongoose');
var BookSchema = new mongoose.Schema({
title: String,
author: String,
publisher: String,
year: Number
});
module.exports=mongoose.model('Book', BookSchema);
HTML
<div class="container" ng-app="myApp" ng-controller="bookCtrl">
<table class="table">
<!--omitted code in between -->
<tr ng-repeat="book in library"> <!-- I tried track by $index and it didn't work-->
<td>{{book.title}} </td>
</tr>
</div>
I think the nodejs response is wrong. The res.json...try another options please.
EDIT: LIke this: res.status(200).send({myBooksList:list})
or this: res.send(200,{myBooksList:list})
Im still not sure :D, sorry.
Change your template's ng-repeat to :
<tr ng-repeat="book in library track by $index">
It doesn't handle duplicate data very well as it tries to find an identifier that is unique for every item. But since there's duplicates in the data angular is unable to do so... We can use the assigned repeat index to track the item by.
This might work:
Book.find(function(err, books) {
if (err)
res.send(err);
res.end(JSON.stringify(books));
}
}));

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