How can I view all ng-init content? - angularjs

I am doing the progress bar for each object equipment.
Here is my AngularJS code:
$scope.progressBarEquipements=function(idEquipement) {
$http.get(url+"/RestResponseCheckLists?idEq="+idEquipement)
.success(function(data) {
$scope.Pourcentage = data;
}).error(function(err, data) {
console.log("error : " +data);
});
};
This function returns $scope.progressBarEquipements=function(idEquipement):
console.log("data "+Pourcentage);
/**
* [{'NB_Resp':2,'NB_checks':154}] //For the first object And the others not
*/
Here is my HTML code:
<div class="col-md-4" ng-repeat="eq in Checksf" ng-init="progressBarEquipements(eq.idEquipements)">
<h4 class="list-group-item-heading" >{{eq.nomEq}} </h4>
<div class="progress progress-lg m-b-5" >
<div class="progress-bar progress-bar-purple" role="progressbar" ng-repeat="p in Pourcentage" ng-style="{width:{{((p.NB_Resp/p.NB_checks) * 100)}} + '%'}">
{{((p.NB_Resp/p.NB_checks) * 100) | number:0}}%
</div>
</div>
</div>
So I have four items of equipment are displayed in the html page.
The $scope.Percentage displays the progress bar calculation for the
first object only.
How to display for each object its calculation in the progress bar?
thank you in advance

Although, I don't like the way you are using ng-init, the following should work :
$scope.progressBarEquipements=function(eq) {
$http.get(url+"/RestResponseCheckLists?idEq="+ eq.idEquipement)
.success(function(data) {
eq.Pourcentage = data;
}).error(function(err, data) {
console.log("error : " +data);
});
};
<div class="col-md-4" ng-repeat="eq in Checksf" ng-init="progressBarEquipements(eq)">
<h4 class="list-group-item-heading" >{{eq.nomEq}} </h4>
<div class="progress progress-lg m-b-5" >
<div class="progress-bar progress-bar-purple" role="progressbar" ng-repeat="p in eq.Pourcentage" ng-style="{width:{{((p.NB_Resp/p.NB_checks) * 100)}} + '%'}">
{{((p.NB_Resp/p.NB_checks) * 100) | number:0}}%
</div>
</div>
</div>
The idea was to send your function "progressBarEquipements" the full equipment object. In that way, you are able to update it when the server responds.
I don't like the approach of using ng-init because
- the behaviour of your view is kinda hidden between your controller, and your template.
- If I had to do it, my API would give the viewmodel containing every information I need to display.

Related

How to limit results with ng-repeat?

Sorry for the basic question, extremely new to software development and angular in particular. I'm currently making a small app that uses an api to find cinemas near a certain postcode.
I have made a results page that show what films are playing in a certain cinema, but I want to limit the amount of results returned and include a 'Show more films' button.
I have included my html and controller below:
HTML
<div class="main-container">
<fountain-header></fountain-header>
<div class="cinemas-container">
<h2 align="center" class="cinemas-h2">Movies playing here:</h2>
<div class="cinema2" ng-repeat="listing in $ctrl.listings">
<h3 class="cinema-h5">{{listing.title}}</h3>
<ul class="cinema-h4">
<li ng-repeat="time in listing.times">{{time}}</li>
</ul>
</div>
<div class="main-container">
</main>
</div>
<fountain-footer></fountain-footer>
</div>
</div>
ListingsController
function ListingsController($http, $stateParams) {
console.log($stateParams);
console.log($stateParams.cinemaID);
var vm = this;
$http
.get('https://api.cinelist.co.uk/get/times/cinema/' + $stateParams.CinemaID +'?day=1')
.then(function (response) {
console.log(response);
vm.listings = response.data.listings;
});
}
Could I just use limitTo to achieve this?
P.S sorry for the poor information, it's my first question on here.
Please try the following example in the fiddle link -
Using the limitTo filter.
ng-repeat="d in data | limitTo: limitvar"
https://jsfiddle.net/m0q9ju8a/
let me know if this helps.
You can do like this:
HTML
<div class="main-container">
<fountain-header></fountain-header>
<div class="cinemas-container">
<h2 align="center" class="cinemas-h2">Movies playing here:</h2>
<div class="cinema2" ng-repeat="listing in vm.listings | limitTo: vm.limit as results">
<h3 class="cinema-h5">{{listing.title}}</h3>
<ul class="cinema-h4">
<li ng-repeat="time in vm.listing.times">{{time}}</li>
</ul>
</div>
<button ng-hide="results.length === vm.listings.length" ng-click="vm.limit = vm.limit +8">show more...</button>
<div class="main-container">
</main>
</div>
<fountain-footer></fountain-footer>
</div>
</div>
and in youn controller
function ListingsController($http, $stateParams) {
console.log($stateParams);
console.log($stateParams.cinemaID);
var vm = this;
vm.limit = 8;
$http
.get('https://api.cinelist.co.uk/get/times/cinema/' + $stateParams.CinemaID +'?day=1')
.then(function (response) {
console.log(response);
vm.listings = response.data.listings;
});
}

Why do I don't get no data back from the array?

I don't get the correct data back. What is my mistake?
var ref = firebase.database().ref("Entries/kategorie");
ref.once("value")
.then(function(snapshot) {
$scope.tmp = snapshot.val();
$scope.$apply(function () {
$scope.data = $scope.tmp
// returns what you see in the image
console.log($scope.tmp.catname);
// The Log statement returns ["Cat1", "Cat2", "Cat3"] so the array which i need.
})
});
This is what i get back.
This is the html
<div ng-repeat="cat in data" class="animated lightSpeedIn">
<a nav-transition="none"><div ng-style="{'background': 'url(' + cat.bgurl + ')','background-repeat': 'no-repeat','background-size': 'cover','display': 'block','width': '100%','height': '25vh' }" class="bgcat center">
<div class="inner">
<h1>{{cat.catname}}</h1>
<h4>{{cat.subtitle}}</h4>
</div>
</div></a>
</div>
I thought with cat.catname it's possible to get the catnameurl. But that seems to be wrong...
Your returned data is in little bit incorrect format. The correct way is to return array of objects
But, you can do this:
<div ng-repeat="catname in data.catname" class="animated lightSpeedIn">
<a nav-transition="none"><div ng-style="{'background': 'url(' + data.bgurl[$index] + ')','background-repeat': 'no-repeat','background-size': 'cover','display': 'block','width': '100%','height': '25vh' }" class="bgcat center">
<div class="inner">
<h1>{{catname}}</h1>
<h4>{{cat.subtitle[$index]}}</h4>
</div>
</div></a>
</div>
You do have a very "unusual" data model. But I leave that up to you. Based on your data model, your html should look like this:
<div ng-repeat="bgurl in data.bgurl" class="animated lightSpeedIn">
<a nav-transition="none"><div ng-style="{'background': 'url(' + bgurl + ')','background-repeat': 'no-repeat','background-size': 'cover','display': 'block','width': '100%','height': '25vh' }" class="bgcat center">
<div class="inner">
<h1>{{data.catname[$index]}}</h1>
<h4>{{data.subtitle[$index]}}</h4>
</div>
I would recommend that you structure your data like this (attention: this structure does not fit the HTML that I just proposed in this answer)
[
{bgurl:'abc', catname:'name1', subtitle:'my first cat'},
{bgurl:'xyz', catname:'name2', subtitle:'my second cat'}
]

post.length stays 0 due to loop - AngularJS

I'm trying to add pagination but I can't seem to figure out this last part.
Everything is setup, though my pagination isn't recording the amount of posts that are linked with the user.
Seeing that I'm doing a forEach and if loop and pushing the retrieved items into a empty collection, my 'posts.length' is returning 0.
Hence the pagination only showing page 1/1 and not 1/2 (for example).
Here is my full code:
profileCtrl.js
Here is the $http.get - I'm trying to get all the posts that the logged in user made doing this loop:
app.controller('profileCtrl', function($scope, auth, $http, $log) {
$scope.auth = auth;
$scope.date = auth.profile.created_at;
$scope.pageSize = 5;
$scope.posts= [];
$http.get('URL')
.then(function(result) {
angular.forEach(result.data, function(data, key) {
if(data.userId === auth.profile.user_id) {
$scope.posts.push(data);
}
});
});
});
profile.html
As you can see, I'm trying to get the length of post in posts using total-items="posts.length":
<div class="col-md-8 no-padding-right">
<div class="panel panel-primary">
<div class="list-group-item active text-center">
<h4 class="no-margin-top no-margin-bottom">Recent Activity</h4>
</div>
<a href="#" class="list-group-item" ng-repeat="post in posts| startFrom: (currentPage - 1) * pageSize | limitTo: pageSize | orderBy :'created_at':true">
<div class="row">
<div class="col-md-4">
<div class="thumbnail no-border no-margin-bottom">
<img src="https://placehold.it/150x150" alt="bird" width="150" height="150"/>
</div>
</div>
<div class="col-md-8">
<h4 class="no-margin-top no-margin-bottom"><strong>{{post.birdname}}</strong></
</div>
</div>
</a>
<uib-pagination total-items="posts.length" ng-model="currentPage" max-size="pageSize" boundary-link-numbers="true"></uib-pagination>
</div>
</div>
app.js
I also added a filter in app.js:
app.filter('startFrom', function() {
return function(data, start) {
return data.slice(start);
}
});
When I console.log(posts.length); I keep getting 0 and I'm guessing it's because of the $scope.posts = []; declared on top (profileCtrl.js).
Edit:
After doing a bit of debugging with console.log, I do get the value given when doing this:
$http.get('url')
.then(function(result) {
angular.forEach(result.data, function(data, key) {
if(data.userId === auth.profile.user_id) {
$scope.posts.push(data);
}
});
console.log($scope.posts.length);
});
How should I fix this?
If you're waiting for data to be returned before loading the collection (with pagination) either add a ng-if="posts.length" to the container, or initialise $scope.posts as being null and add ng-if="posts" if you want the list to show when the API returns 0 results. This will prevent Bootstrap's pagination directive being parsed until the data it needs is available.
Edit: After debugging, the following plunkr contains a working implementation: http://plnkr.co/edit/VQjNVK6gRKsCqxVb54nR?p=preview

Data can not be synchronized using angularjs

I store a data in a factory like this:
module.factory('AddedStockListData', function(){
var list= [];
var size = 0;
return{
getList: function(){
return list;
},
setList: function(data){
list = data;
},
getSize:function(){
return size;
},
setSize:function(){
size++;
},
setDelSize:function(){
size--;
}
}
});
And in my controller the code as follows:
$scope.stocksSearchList = AddedStockListData.getList();
$scope.load = function($done){
$timeout(function() {
document.getElementById("showTipsToDropDown").style.display = "none";
$scope.stocksSearchList = AddedStockListData.getList();
$done();
}, 500);
}
My html like this:
<ons-page ng-controller="createPortStockController">
<ons-pull-hook ng-action="load($done)" var="loader" id="pullDown">
<span ng-switch="loader.getCurrentState()">
<span ng-switch-when="initial"><ons-icon size="35px" icon="ion-arrow-down-a"></ons-icon> Pull down to refresh</span>
<span ng-switch-when="preaction"><ons-icon size="35px" icon="ion-arrow-up-a"></ons-icon> Release to refresh</span>
<span ng-switch-when="action"><ons-icon size="35px" spin="true" icon="ion-load-d"></ons-icon> Loading data...</span>
</span>
</ons-pull-hook>
<div>
<ons-toolbar class="DCF" fixed-style>
<div class="left">
<ons-back-button style="color:white;"></ons-back-button>
</div>
<div class="center" style="font-size:22px;" >Create Portfolio</div>
<div ng-click="create()"class="right" style="font-size:18px;color:white;margin-top:10px;padding-right:10px;" >Create</div>
</ons-toolbar>
<div class="addStockButton" ng-click = "myNavigator.pushPage('portStockSearchList.html', { animation : 'slide'})">
<i class="fa fa-plus" ></i>Add Stock
<p id="showTipsToDropDown"style="margin:0px;font-size:12px;text-align:center;color:#adadad;">After your first time add stocks, please drop down to refresh</p>
</div>
<div class="stockSearchList">
<div ng-repeat="stockSearch in stocksSearchList">
<div class="stockSearchOne">
<div class="stockSearchOneComp">{{stockSearch.company}}</div>
<div class="stockSearchOneInfo">Symbol: {{stockSearch.symbol}} | Exchange:{{stockSearch.exchange}} </div>
</div>
</div>
</div>
</div>
Actually, I change the factory data in next page,I want to make this page change the display while the factory data is changed.
But the result is , at the first time I change the data in the next page and back to this page, the data will not display, and I will refresh this page by use the ons-pull-hook> and then if I go to the next page to change the data, when I back to here, data will be synchronized display .
So the result is at the first time , I have to refresh the page to get the data, but after the first time, I don't need to do this
Anybody can help me to solve this problem?
Try using $scope.$apply() after the data have been fetched, it should update the content without any need to refresh the page. You can learn more about $scope.$apply() here.

AngularJs how to reload a template page after selecting a charater

I am using http.get and i need to reload a template after selecting a character so that my template gives the answer according to what I selected
The code of the template
<div class="container-fluid" ng-controller="CriterioCtrl">
<div id="result"></div>
<div>
Selected Items:
<div ng-repeat="id in selection">
{{id}}
</div>
</div>
<div ng-repeat-start="crit in data" class="row">
<h2 align="center">{{crit.name}}</h2>
<div ng-repeat="caracter in crit.characters" class="col-md-4">
<div type="checkbox" value="{{caracter.id}}" ng-checked="selection.indexOf(caracter.id) > -1" ng-click="clickSelection(caracter.id)">
<a href="#crit" class="thumbnail" ng-click="clickCriterios(caracter.id)">
<h4 align="center">{{caracter.name}}</h4>
<img ng-src="http://skaphandrus.com/{{caracter.image_url}}"/>
</a>
</div>
</div>
</div>
<div ng-repeat-end>
</div>
<!--<button class="btn" ng-click="toggle()">Toggle</button>
<p ng-show="visible">Hello World!</p> codigo de um botao -->
</div>
This code is for the selection
$scope.selection=[];
$scope.clickSelection = function clickSelection(caracterId) {
var idx = $scope.selection.indexOf(caracterId);
// is currently selected
if (idx > -1) {
$scope.selection.splice(idx, 1);
}
// is newly selected
else {
$scope.selection.push(caracterId);
}
var selectedId = $scope.selection;
console.log(selectedId);
// Check browser support
if (typeof(Storage) != "undefined") {
// Store
localStorage.setItem("idSelect", selectedId);
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("idSelect");
}
};
This code is the http part in another controller
MyApp.controller('EspeciesCtrl', function ($scope, $http) {
$http({
url: 'someurl',
method: "post",
params: {module_id: localStorage.getItem("idMod"),"characters[]": [localStorage.getItem("idSelect")]}
})
.then(function(res){
$scope.data = res.data;
});
});
This is the code of the template that have to change after the selection
<div class="container-fluid" ng-controller="EspeciesCtrl">
<div class="row">
<div ng-repeat="esp in data" class="col-md-6">
<a href="#infEsp" class="thumbnail" ng-click="clickEspecie(esp.id)">
<h4 align="center">{{esp.name}}</h4>
<img ng-src="{{esp.image_src}}"/>
</a>
</div>
</div>
</div>
How can i do that?
edit 1
If I've correctly understood, you may need to use ng-show (https://docs.angularjs.org/api/ng/directive/ngShow) whose boolean value checks if the user selected anything and show the extra bit of code you need, instead of trying to have another http request.
Also, it seems like you are using $scope.data for both the esp and the crit, so you will end up with the errors.
You probably don't need to reload the template.
You may want to use the data in $scope.data inside the template in order to let Angular manage the update on the view. As soon as the $scope.data changes, the rendered HTML changes too.
I can't comment but it would be helpful if you could share the template you are using and be more specific in your request :)

Resources