Use AngularJS $http.get to repeatedly request JSON array on scrolling - javascript

Below is a snippet using AngularJS to get the JSON response.
On scrolling to the bottom of the page, I need to request repeatedly till the JSON array list is empty.
<section>
<div style="padding-top:60px" infinite-scroll="myPagingFunction()" infinite-scroll-distance="3" ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="news in newsList">
<div class="col-lg-3 col-md-4 col-sm-6" style="">
<div class="thumbnail">
<img src="{{news.coverUrl}}" class="img-responsive" alt="{{news.name}}"/>
<div class="caption">
<h4>{{news.name}}</h4>
</div>
</div>
</div>
<div class="visible-lg clearfix" ng-if="($index+1)%4 == 0"></div>
<div class="visible-md clearfix" ng-if="($index+1)%3 == 0"></div>
<div class="visible-sm clearfix" ng-if="($index+1)%2 == 0"></div>
</div>
</div>
</section>
<script src="js/jquery.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="js/ng-infinite-scroll.min.js"></script>
<script>
var offset = 0
var maxCount = 20
var app = angular.module('myApp', ['infinite-scroll']);
function myPagingFunction(){
app.controller('myCtrl', function($scope, $http) {
$http.get("news.json").then(function(response) {
$scope.newsList = response.data;
});
});
}
myPagingFunction();
</script>
<script src="js/bootstrap.min.js"></script>
Kindly help me in solving this.

Using jQuery + angular is not good
You must use angular way instead, and write some directives or listeners in run phase, but here's a better approach - use `ngInfiniteScroll plugin

You can simply use infinite Scroll services to easily achieve this ,
<ANY infinite-scroll='{expression}'
[infinite-scroll-distance='{number}']
[infinite-scroll-disabled='{boolean}']
[infinite-scroll-immediate-check='{boolean}']
[infinite-scroll-listen-for-event='{string}']>
Add ng-infinite scroll module in your application
for more info refer this [Documentation]:(https://sroze.github.io/ngInfiniteScroll)

You can use this simple directive and enjoy:
app.directive("scroll",['$window', function ($window) {
return function (scope, element, attrs) {
angular.element($window).bind("scroll", function () {
if (document.body.scrollHeight - $window.scrollY < 890) {
scope.$apply(function () {
scope.myPagingFunction();
});
}
});
};
}]);
and you can use this code for your situation
<section>
<div style="padding-top:60px" scroll ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="news in newsList">
<div class="col-lg-3 col-md-4 col-sm-6" style="">
<div class="thumbnail">
<img src="{{news.coverUrl}}" class="img-responsive" alt="{{news.name}}"/>
<div class="caption">
<h4>{{news.name}}</h4>
</div>
</div>
</div>
<div class="visible-lg clearfix" ng-if="($index+1)%4 == 0"></div>
<div class="visible-md clearfix" ng-if="($index+1)%3 == 0"></div>
<div class="visible-sm clearfix" ng-if="($index+1)%2 == 0"></div>
</div>
</div>
</section>
<script src="js/jquery.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="js/ng-infinite-scroll.min.js"></script>
<script>
var offset = 0
var maxCount = 20
var app = angular.module('myApp', ['infinite-scroll']);
app.controller('myCtrl', function ($scope, $http) {
$scope.myPagingFunction= function() {
$http.get("news.json").then(function (response) {
$scope.newsList = response.data;
});
}
});
app.directive("scroll",['$window', function ($window) {
return function (scope, element, attrs) {
angular.element($window).bind("scroll", function () {
if (document.body.scrollHeight - $window.scrollY < 890) {
scope.$apply(function () {
scope.myPagingFunction();
});
}
});
};
}]);
</script>
<script src="js/bootstrap.min.js"></script>

Related

how to use $scope inside .on click event?

I'm very new to Angular js and am testing a few functions with a simple data-parser project (Plunkr). Right now, I'm having trouble accessing $scope variable within a jQuery on click event. I would like to keep some elements hidden until an image is clicked. While I can set ng-hide to true within the controller, $scope does not appear to work inside an on click handler. Please help.
zodiac.html
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div id="container" ng-app="myApp" ng-controller="myCtrl">
<div>
<h1>What Animal Are You?</h1>
<div id="selectPicture"></div>
</div>
<div id="zodiac" ng-hide="disappear">
<h1>Your Zodiac</h1>
<div id="your-zodiac">
</div>
<br>
<h1>Avoid these Animals</h1>
<div id="hateDiv">
</div>
<br>
<h1>These Are Your Besties</h1>
<div id="loveDiv">
</div>
</div>
<script src="scripts.js"></script>
</div>
</body>
scripts.js
function d(c) {
console.log(c)
}
var app = angular.module('myApp', [])
app.controller('myCtrl', function($scope, $http) {
$http.get('zodiac.json').success(function(data) {
$scope.disappear = true //WORKS HERE
$scope.animalsData = data
angular.forEach($scope.animalsData, function(item) {
$('#selectPicture').prepend('<img src="' + item.picture + '" alt="' + item.animal + '">')
})
$('#selectPicture').on('click', 'img', function($scope) {
$scope.disappear = false //DOES NOT WORK HERE
$('#zodiac div').empty();
findZodiac(this.alt, "#your-zodiac", true);
})
function findZodiac(animal, e, test) {
angular.forEach($scope.animalsData, function(item) {
if (item.animal == animal) { //look for the right object 'item', when found, get the image
//item.picture
$(e).prepend('<img src="' + item.picture + '">')
if (test == true) {
loveHate(item.hate, "#hateDiv")
loveHate(item.love, "#loveDiv")
}
return
}
})
}
function loveHate(array, e) {
angular.forEach(array, function(value) { //loops through an array, get each animal
findZodiac(value, e, false)
})
}
});
})
In my opinion you should not do DOM manipulation directly when using AngularJS. Use the directives provided by AngularJS instead. Here are the template and controller code if you do so -
zodiac.html
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div id="container" ng-app="myApp" ng-controller="myCtrl">
<div>
<h1>What Animal Are You?</h1>
<div id="selectPicture">
<img ng-repeat="animal in animalsData"
ng-src="{{animal.picture}}"
alt="{{animal.animal}}"
ng-click="disappear=false; findZodiac(animal)" />
</div>
</div>
<div id="zodiac" ng-hide="disappear">
<h1>Your Zodiac</h1>
<div id="your-zodiac">
<img ng-src="{{selectedAnimal.picture}}" alt="{{selectedAnimal.animal}}" />
</div>
<br>
<h1>Avoid these Animals</h1>
<div id="hateDiv">
<img ng-repeat="animal in selectedAnimal.hate"
ng-src="{{animal.picture}}"
alt="{{animal.animal}}" />
</div>
<br>
<h1>These Are Your Besties</h1>
<div id="loveDiv">
<img ng-repeat="animal in selectedAnimal.love"
ng-src="{{animal.picture}}"
alt="{{animal.animal}}" />
</div>
</div>
<script src="scripts.js"></script>
</div>
</body>
scripts.js
var app = angular.module('myApp', [])
app.controller('myCtrl', function($scope, $http) {
$scope.animalsData = [];
$scope.selectedAnimal = {};
$scope.disappear = true;
$scope.findZodiac = function(animal) {
$scope.selectedAnimal = animal;
};
$http.get('zodiac.json').success(function(data) {
$scope.animalsData = data;
});
});
In AngularJS $scope is a global variable for your controller, You don't need to pass it like this. directly use it as
$('#selectPicture').on('click','img',function(){
$scope.disappear=false;//this will work
$('#zodiac div').empty();
findZodiac(this.alt,"#your-zodiac",true);
})
check this corrected version
scope object only available in angular world.

How to ng-if another div is visible

I have two lists of stuff using ng-repeat. Then I want it to say "empty" if there are no items in a list.
Here's the updated version:
<!-- First List -->
<div ng-repeat="request in requests" ng-if="request.condition1 == 'something'">
{{request}}
</div>
<div>Empty list</div>
<!-- Second List (both use requests array but have different conditions-->
<div ng-repeat="request in requests" ng-if="request.condition22222 == 'something else'">
{{request}}
</div>
<div>Empty list</div>
Try this:
(function(angular) {
'use strict';
angular.module('app', [])
.filter('decorate', function() {
return function(input, model) {
return input.filter(function(val){
return val[model.prop] == model.val;
});
};
}).controller('MyController', ['$scope', '$filter', function($scope, $filter) {
$scope.requests = [{name:'Tom', age:23},{name:'Henry', age:23},{name:'Max', age:33}];
$scope.$filter = $filter;
}])
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<div ng-controller="MyController">
<div ng-init='items1=$filter("decorate")(requests, {prop:"age", val:23})'>First list(age=23):</div>
<div ng-repeat='item in items1' ng-if='items1.length > 0' >{{item | json}}</div>
<div ng-if='items1.length == 0'>Empty</div>
<br/>
<div ng-init='items2=$filter("decorate")(requests, {prop:"name", val:"Sam"})'>Second list(name=Sam):</div>
<div ng-repeat='item in items2' ng-if='items2'>{{item | json}}</div>
<div ng-if='items2.length == 0'>Empty</div>
</div>
</body>
You can check against the length of your list and show it conditionally:
<div ng-show="!requests.length">List is empty</div>
If you're working with an object you can use Object.keys although it may not be supported in some older browsers.

Angular trigger js 'onclick' event

I'm trying to trigger an 'onclick' event inside of an angular controller.
<div id="galerie">
<h2>{{main.Page.title()}}</h2>
<hr>
<div class="row">
<div class="col-sm-4 col-xs-6" ng-repeat="i in page.getLans() track by $index">
<a ng-click="page.selectGalerie($index+1)" href>Playground Vol.{{$index+1}}</a>
</div>
</div>
<div id="links">
<a id="galerieLink_{{$index}}" href="img/galerie/pg{{page.galerie.volume}}/{{file}}" ng-repeat="file in page.galerie.files">{{$index}} </a>
</div>
<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev">‹</a>
<a class="next">›</a>
<a class="close">×</a>
<a class="play-pause"></a>
<ol class="indicator"></ol>
</div>
</div>
<script>
document.getElementById('links').onclick = function (event) {
event = event || window.event;
var target = event.target || event.srcElement;
var link = target.src ? target.parentNode : target;
var options = {index: link, event: event};
console.log(options);
var links = this.getElementsByTagName('a');
blueimp.Gallery(links, options);
};
</script>
I was trying it this way inside my controller:
angular.element('#galerieLink_0').trigger('click');
But it doesn't work.
Angular is not jquery. functionality belongs in the controller.
var app = angular.module("app", []);
app.controller("foo",["$scope",function($scope){
$scope.clickCount = 0;
$scope.counter = function() { $scope.clickCount++; }
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="foo">
<div ng-bind="clickCount"></div>
<button ng-click="counter()" >+1</button>
</div>

evaluating scope object with a element attribute in AngularJS

I'm learning AngularJs. I following this example with a few modification and i dont get it why it does not work.
The example is as follow:
<html ng-app="app">
<head>
<title>Calendar</title>
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="angular.min.js"></script>
<script>
angular.module('app', [])
.controller('dayCtrl', dayCtrl)
.directive('highlight', highlight);
function dayCtrl ($scope){
var daysName = ['Sunday', 'Monday', 'Tuesday'];
$scope.data = {
day : daysName[new Date().getDay()],
tomorrow : daysName[(new Date().getDay() + 1)]
};
}
function highlight () {
return function (scope, element, attrs){
if(scope.day == attrs['highlight']){
element.css('color', 'red');
}
}
}
</script>
</head>
<body>
<div class="container">
<div class="row panel" ng-controller="dayCtrl">
<div class="col-sm-12 page-header clearfix">
<h4>Angular App</h4>
</div>
<h4 highlight="Monday">
Today is {{ data.day || 'unknown'}}
</h4>
<h4>
Tomorrow is {{ data.tomorrow || 'unknown' }}
</h4>
</div>
</div>
</body>
I hope you can help me with this little thing
Try like this with scope.data.day in your angular directive:
function dayCtrl($scope) {
var daysName = ['Sunday', 'Monday', 'Tuesday'];
$scope.data = {
day: daysName[new Date().getDay()],
tomorrow: daysName[(new Date().getDay() + 1)]
};
}
function highlight() {
return function(scope, element, attrs) {
if (scope.data.day == attrs['highlight']) {
element.css('color', 'red');
}
}
}
angular.module('app', [])
.controller('dayCtrl', dayCtrl)
.directive('highlight', highlight);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div class="row panel" ng-controller="dayCtrl">
<div class="col-sm-12 page-header clearfix">
<h4>Angular App</h4>
</div>
<h4 highlight="Monday">
Today is {{ data.day || 'unknown'}}
</h4>
<h4>
Tomorrow is {{ data.tomorrow || 'unknown' }}
</h4>
</div>
</div>

materialbox Materializecss works only after typing initialization jQuery in console

I have used '.materialboxed' in my webpage, but the initialization in script doesn't work, I have to manually type $('.materialboxed').materialbox(); in console for it to work.
Html (ui-view in angular route)
<div class="row">
<div class="card-panel col l12" style="height: 750px;">
<img class="col l5 materialboxed" height="500px" id="poster"
ng-src="https://image.tmdb.org/t/p/original{{poster_path}}"/>
<div class="col l7">
<div class="row">
<a class="col l10" style="float:left;text-align: left;" ng-href="{{homepage}}">
<h3 class="title" ng-bind="original_title"></h3>
</a>
<a ng-href="http://www.imdb.com/title/{{imdb_link}}"
style="float:right;text-align: right; margin-top: 29px;"
class="imdb-link col l2" title="IMDb"><i class="icon-imdb"></i></a>
</div>
<div class="row"><p ng-bind="overview"></p>
<span class="right" ng-bind="release_date"></span>
<h5>Genres</h5>
<p ng-bind="genre"></p>
<h5>Production Companies</h5>
<p ng-bind="names">
</p>
<h5>Voting</h5>
<p ng-bind="vote_average"></p></div>
</div>
</div>
</div>
See the in 3rd line.
index.html
//rest code
<main ui-view></main>
</div>
<script src="js/angular_min.js"></script>
<script src="js/angular-touch.min.js"></script>
<script src="js/angular-ui-router.min.js"></script>
<script src="js/angucomplete-alt.js"></script>
<script src="appRoute.js"></script>
<script src="controller/MovieController.js"></script>
<script src="controller/LoginController.js"></script>
<script src="controller/RegisterController.js"></script>
<script src="controller/TvController.js"></script>
<script src="controller/LoggedInController.js"></script>
<script src="controller/TopMovieController.js"></script>
<script src="app-services/DetailsService.js"></script>
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/materialize.min.js"></script>
<script>
$(document).ready(function () {
$('.materialboxed').materialbox();
$('.button-collapse').sideNav({
menuWidth: 300,
edge: 'left',
closeOnClick: true
}
);
$('.modal-trigger').leanModal();
$("#movie").click(function () {
window.location.href = window.location.pathname + "#/movie";
});
$("#tv").click(function () {
window.location.href = window.location.pathname + "#/tv";
});
});
</script>
</body>
Even after initializing the materialboxed, it doesn't work. It works only after typing $('.materialboxed').materialbox(); in console manually.
Help me figure this out. Thanks
You shouldn't use $(document).ready in Angular. In fact you should try to use as little jQuery as possible, but if you need to, then you should create a directive that allows you to initialize the function after they render.
var app = angular.module('myApp');
app.directive('onLastRepeat', function() {
return function(scope, element, attrs) {
if (scope.$last)
setTimeout(function() {
scope.$emit('onRepeatLast', element, attrs);
}, 1);
};
});
app.controller('MoviesController', function($scope) {
$scope.$on('onRepeatLast', function(scope, element, attrs) {
$('.materialboxed').materialbox();
});
}
Now you can apply this to your HTML:
<ul>
<!-- this is just an example with the added directive -->
<li ng-repeat="movie in movies" on-last-repeat>
<img ng-src="{{imageObjectHere}}" class="materialboxed">
</li>
</ul>
Since you added this new directive in there, the $('.materialboxed').materialbox(); should fire after the repeat is done

Categories