Ionic Pagination starting - angularjs

I am trying to create a pagination feature but I feel stuck. I am not sure if I am on the right track...
in my view, I have an ng-repeat=" res in result", and at the end of the page i placed the following:
<ion-infinite-scroll on-infinite="loadMore()" distance="1%"></ion-infinite-scroll>
then in the controller, i wrote this:
var i=1;
$http.get( "http://website/search/"+i).success(function(response){
i++;
$scope.result=(response)
});
}
each pages returns a json containing 15 elements. What I want to do is when i reach the end, I want to load the next 15 in the result to be displayed.

You have to fetch next 15 item in loadMore function in controller as you write on-infinite="loadMore()" in ion-infinite-scroll
Write function as follow in your controller
$scope.result = [];
var i=1;
$scope.loadMore = function(){
$http.get( "http://website/search/"+i).success(function(response){
i++;
$scope.result.push(response);
});
}
Check Example

Hears how I have implemented infinite-scroll in my app
<ion-infinite-scroll ng-if="!loadMorePeople" on-infinite="loadPeople()" distance="1%"></ion-infinite-scroll>
loadPeople() loads all the scrolled data, it's code is bellow
$scope.loadMorePeople=false;
$scope.loadPeople = function() {
if($scope.peoples != null){
$http({
method: "get",
url: baseUrl+"company-members?page="+$scope.pagePeople,
withCredentials: true,
headers: {
'Accept' : 'application/json, text/plain, */*',
'Authorization' : ''+window.localStorage.getItem("token_type")+' '+window.localStorage.getItem("token")
}
})
.success(function(data) {
if(data.length > 0){
var newPeople = data;
$scope.temp = $scope.peoples.concat(newPeople);
$scope.peoples = arrayUnique($scope.temp, 'id');
function arrayUnique(collection, keyname) {
var output = [],
keys = [];
angular.forEach(collection, function(item) {
var key = item[keyname];
if(keys.indexOf(key) === -1) {
keys.push(key);
output.push(item);
}
});
return output;
};
++$scope.pagePeople;
$scope.$broadcast("scroll.infiniteScrollComplete");
}else{
$scope.loadMorePeople=true;
$scope.$broadcast("scroll.infiniteScrollComplete");
}
})
.error(function(data, status) {
});
}
$scope.$broadcast("scroll.infiniteScrollComplete");
};
I too had the same problem as you for some reason .push() was not working so I did this workaround.
I took the data checked if it's not null in if(data.length > 0){} and then used .concat(newPeople) to merge them and finally used arrayUnique($scope.temp, 'id') to make sure that there is no duplicate entity.
It's also a good idea to use ng-if="!loadMorePeople" it help to stop the call if there is no data left to fetch else the call will continously go on.
I hope this solves your problem. Let me know if you need any help :D

Related

How to send an object and array through Angularjs service

I am trying to send an object and array in the same time to an API, but i got an error
This is the object (from input boxes)
var vacation = {
Vac_Main_Key: $scope.vackey, Vac_Main_Code: $scope.code, Gender_Type: $scope.gen, CareeService_Flag: $scope.career, Vac_Duration: $scope.vduration,
Duration_Flag: $scope.vflag}
This is the array (from multiple check boxes)
$scope.selectedcontract = function (con)
{
if (con.details == true) {
$scope.vacationcontracts.push({ VacMKey: $scope.vackey, WType: con.sys_key });
console.log($scope.vacationcontracts);
}
else if (con.details == false) {
$scope.vacationcontracts.splice(con, 1);
}
}
The save button
var promisePost = vacationsetupSrv.save(vacation, $scope.vacationcontracts);
promisePost.then(function () {}
The angularjs service:
var vacationsetup = angular.module("vacationsetup", [])
.service("vacationsetupSrv", function ($http) {
var urlBase = "/VacationSetupAPI/api";
this.save = function (url, vacation,vacationcontracts) {
return $http({
method: "POST",
url: urlBase + '/' + url,
data: vacation, vacationcontracts,
async: false,
})
};
i got this error http://localhost/VacationSetupAPI/api/[object%20Object]
Any help, Thanks in advance
Try
this.save = function (vacation,vacationcontracts) {
You are sending object as 1st argument and then assigning it to the url as string, that’s wrong.
vacationsetupSrv.save(vacation, $scope.vacationcontracts);
OR
Try
vacationsetupSrv.save(“”,vacation, $scope.vacationcontracts);

AngularJS Count Yes/No Values

I'm currently working on a AngularJS / Parse.com web application
What I'm trying to achieve:
I would like to get the total amount of Yes & No values within an Array.
e.g Yes = 3 No = 6
Current Problems:
I've managed to get all Yes & No values from Parse and put them into an Array but I'm unable to count the amount of Yes or No values.
Any help / advice would be helpful!
HTML:
<md-card>
<md-card-content>
<canvas id="doughnut" class="chart chart-doughnut" data="widgetone_data" labels="widgetone_label"></canvas>
</md-card-content>
{{widgetone_data | json}}
</md-card>
Controller JS:
dashApp.controller("dashboardCtrl", function ($scope, $http, $filter) {
$scope.parseRecommendations = [];
$http({
method : 'GET',url : 'https://api.parse.com/1/classes/Customers',
headers: { 'X-Parse-Application-Id':'xxx', 'X-Parse-REST-API-Key':'xxx'}
})
.success(function(data, error) {
$scope.parseResults = data.results;
angular.forEach($scope.parseResults, function(results) {
$scope.parseRecommendations.push(results.question_4_p1);
});
})
.error(function(data, error) {alert('Failed, error code: ' + error.message);
});
// Recommend YES/NO
var yesAmount = $filter('filter')($scope.parseRecommendations, { isSelected: 'yes' }).length;
var noAmount = $filter('filter')($scope.parseRecommendations, { isSelected: 'no' }).length;
$scope.widgetone_label = ["Yes", "No"];
$scope.widgetone_data = [yesAmount,noAmount];
});
You can use the .filter() method.
Moreover, you made an error, because you start to filter your data when the controller is instantiated, but your API call is asynchronous, so you have to filter your data into the .success() callback, otherwise you will filter an empty array.
EDIT : To improve performance, you can count your by simulating an hashmap. See below
dashApp.controller("dashboardCtrl", function ($scope, $http, $filter) {
$scope.parseRecommendations = [];
var hashmap = {};
$http({
method : 'GET',url : 'https://api.parse.com/1/classes/Customers',
headers: { 'X-Parse-Application-Id':'wmWxU64vx0QgKBiNQkx9jCDNO6UZDRrM6WkxAbTL', 'X-Parse-REST-API-Key':'0FHcBHZdeUJHKT8j0VQH0hQdN4TZ8qsOBxyd1rG3'}
})
.success(function(data, error) {
$scope.parseResults = data.results;
angular.forEach($scope.parseResults, function(results) {
$scope.parseRecommendations.push(results.question_4_p1);
});
$scope.parseRecommendations.forEach(function(elm){
hashmap.hasOwnProperty(elm)
? ++hashmap[elm]
: hashmap[elm] = 1
});
//Filter yes
var yesAmount = hashmap.yes;
//Filter no
var noAmount = hashmap.no;
$scope.widgetone_label = ["Yes", "No"];
$scope.widgetone_data = [yesAmount,noAmount];
console.log($scope.widgetone_data);
})
.error(function(data, error) {alert('Failed, error code: ' + error.message);
});
});

AngularJS scope refresh on post to API through restangular

I have a controller which loads data via Restangular like so:
var oneTopic = Restangular.one('topics', topic.id);
oneTopic.get({}, {"Authorization" : localStorageService.get('***')}).then(function(topic) {
topic.getList('comments', {}, {"Authorization" : localStorageService.get('***')}).then(function(comments){
$scope.comments = comments;
//console.log($scope.comments);
});
});
And then a function which posts a new comment and one that deletes a comment.
$scope.delComment = function(comment_id, author_id){
var comment = Restangular.one('comments', comment_id);
comment.remove({author_id: author_id}, {"Authorization" : localStorageService.get('***')}).then(function(){
// need to perform refresh here
});
};
$scope.postComment = function(mood) {
$scope.commentData.mood = mood;
comments.post($scope.commentData, {}, {"Authorization" : localStorageService.get('***')}).then(function(response){
// need to perform refresh here
}, function(response){
$scope.error = response.data.message;
})
};
How would I refresh the comments scope without reloading the page? The data is being populated in the HTML with an
<div ng-repeat="comment in comments">
Modify the existing array referenced by $scope.comments and the data binding will take care of it.
For example:
$scope.delComment = function(comment_id, author_id) {
var comment = Restangular.one('comments', comment_id);
comment.remove({ author_id: author_id }, { "Authorization": localStorageService.get('***')
}).then(function() {
// Some remove-from-array implementation, for example:
var c = $scope.comments;
for(var i = 0, l = c.length; i < l; i++) {
if (c[i].comment_id === comment_id) {
c = c.splice(i, 1);
break;
}
}
});
};

Angularjs how to stop infinity scroll when server has no more data to send

Based on THIS example which I have modified with an Ajax request to get the data Im struggling to find a way to stop it when the server has no more data to send.
I have tried to add a boolean variable in a service, and a $watch method in the directive but it is not working.
Is there a simple way to to achieve that ?
This is not my code but if there is no easy answer I can post my code with the changes I have done.
thanks for your help.
<div id="fixed" when-scrolled="loadMore()">
<ul>
<li ng-repeat="i in items">{{i.id}}</li>
</ul>
</div>
function Main($scope) {
$scope.data = { comments : [] }
$scope.loadMore = function(){
$http({
url: '/comment/next',
method: "POST"
})
.success(function(data){
for(var i=0; i<data.length; i++){
$scope.data.comments.push(data[i]);
}
});
}
}
angular.module('scroll', []).directive('whenScrolled', function() {
return function(scope, elm, attr) {
var raw = elm[0];
elm.bind('scroll', function() {
if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
scope.$apply(attr.whenScrolled);
}
});
};
});
I can only guess as to a solution without seeing more of your code (specifically what is returned by $http results), but I believe this sort of thing could work, depending on the structure of a comment object.
function Main($scope) {
$scope.data = { comments : [] }
$scope.scrollComplete = false;
$scope.loadMore = function(){
if($scope.scrollComplete || $scope.loading) { return; }
$scope.loading = true;
$http({
url: '/comment/next',
method: "POST"
})
.success(function(data){
for(var i=0; i<data.length; i++){
var totalComments = $scope.data.comments.length;
if($scope.data.comments[totalComments - 1].someID === data[i].someID){
$scope.scrollComplete = true;
}else{
$scope.data.comments.push(data[i]);
}
}
$scope.loading = false;
}).error(function(){ $scope.loading = false });
}
}
Just bear in mind that a solution like this isn't really elegant. What I like to do is allow an item ID to be passed to the API (i.e. your /comment/next), and treat that as the last grabbed item. So the API will only give me back everything after that. Using that method, you would simply have to pass the last comment ID to the API.

AngularJS - Append to a model with a $resource

I have this service:
factory('Post', function($resource) {
return $resource('/api/post.json', {},
{
query: {method:'GET', isArray: false}
}
);
})
And I have this controller:
function PostsCtrl($scope, Post) {
// init
$scope.page = 0;
$scope.page_has_next = true;
$scope.loadMore = function() {
if($scope.page_has_next) {
$scope.posts = Post.query({page: ++$scope.page},
function(data) {
$scope.page_has_next = data.has_next;
}
);
}
}
$scope.loadMore();
}
This works just fine, each time loadMore() is executed the model gets updated with the next page until there are no more pages. However, I want to append the new set of posts to the current model instead of replacing it, how can I do that?
Assuming that posts is a array:
$scope.posts = $scope.posts.concat(Post.query({page: ++$scope.page})
This will only work if the new posts has no duplicates with the old posts. If there are duplicates, you have to traverse the array and push only new posts.

Resources