I have a angularJS file like this; I need to call the newGame function in the end of the controller not in html. Can anyone help me with this?
var app = angular.module("myApp", []);
app.controller("myCtrl", function ($scope) {
$scope.newGame = function () {
$scope.random = Math.floor(Math.random() * 100) + 1;
$scope.display = "Start guessing";
};
$scope.giveUp = function () {
$scope.display = $scope.random;
};
$scope.check = function () {
if ($scope.guess > $scope.random) {
$scope.display = "Guess Higher"
} else if ($scope.guess < $scope.random) {
$scope.display = "Guess Lower"
} else {
$scope.display = "You got it!"
}
};
});
It's a function just like any other function. Add $scope.newGame(); at the end of your controller.
Related
I created a simple angular function. The purpose is to display a changing value of variable x after pressing a button which triger the function startAction. It is not working and I have no idea why.
var app = angular.module("myApp", []);
app.controller('myController', ($scope, fabryka) => {
$scope.startAction = function () {
setInterval(function () {
var x = 0;
$scope.x = (function () {
x++;
return x;
})();
}, 500);
}
});
Angular has its own setInterval wrapper: $interval.
This piece of code counts seconds as you press the button. Please note the interval cancellation when the scope is destroyed.
angular.module('app', [])
.controller('mainCtrl', function($scope, $interval) {
var vm = this;
vm.x = 0;
var interval;
vm.startAction = function() {
vm.isRunning = true;
interval = $interval(function() {
vm.x++;
}, 1000);
};
vm.stopAction = function() {
vm.isRunning = false;
$interval.cancel(interval);
}
$scope.$on('$destroy', vm.stopAction);
return this;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="mainCtrl as vm">
<div>x: {{vm.x}}</div>
<button ng-click="!vm.isRunning? vm.startAction():vm.stopAction()">{{vm.isRunning? 'Pause':'Start'}}</button>
</div>
I am using wordpress as a backend for an app and I want to use infinite scroll but I am having trouble concatenating articles.
I am calling the service using a factory:
.factory('Worlds', function ($http) {
var worlds = [];
storageKey = "worlds";
function _getCache() {
var cache = localStorage.getItem(storageKey );
if (cache)
worlds = angular.fromJson(cache);
}
return {
all: function () {
return $http.get("http://www.examplesite.com/tna_wp/wp-json/posts?filter[category_name]=international&filter[posts_per_page]=10").then(function (response) {
worlds = response.data;
console.log(response.data);
return worlds;
});
},
GetNewPosts: function () {
return $http.get("http://www.examplesite.com/tna_wp/wp-json/posts?filter[category_name]=international&filter[posts_per_page]=2").then(function (response) {
worlds = response.data;
console.log(response.data);
return worlds;
});
},
get: function (worldId) {
if (!worlds.length)
_getCache();
for (var i = 0; i < worlds.length; i++) {
if (parseInt(worlds[i].ID) === parseInt(worldId)) {
return worlds[i];
}
}
return null;
}
}
})
and my controller looks like this:
.controller('WorldCtrl', function ($scope, $stateParams, $timeout, _, Worlds) {
$scope.worlds = [];
Worlds.all().then(function (data){
$scope.worlds = data;
window.localStorage.setItem("worlds", JSON.stringify(data));
},
function (err) {
if(window.localStorage.getItem("worlds") !== undefined) {
$scope.worlds = JSON.parse(window.localStorage.getItem("worlds"));
}
}
);
$scope.loadMore = function() {
Worlds.GetNewPosts().then(function (worlds){
var loadedIdss = _.pluck($scope.worlds, 'id');
var newItemss = _.reject(worlds, function (item){
return _.contains(loadedIdss, item.id);
});
$scope.worlds = newItemss.concat($scope.worlds);
$scope.$broadcast('scroll.infiniteScrollComplete');
});
};
})
I am trying to use underscore to ignore the posts that are already loaded, however when i try the infinite scroll it just goes into a loop calling more posts but doesnt add them to my ng-repeat and ionicLoading renders the app useless.
ion-infinite-scroll works with some sort of paginated result and you seem to feed your list with all the results.
Your API should look something like this:
http://www.examplesite.com/tna_wp/wp-json/posts?filter[category_name]=international&filter[posts_per_page]=2&filter[page]=1
notice I've added a page filter.
and your service responsible to fetch the data should look something like this:
.factory('dataService', function($http) {
return {
GetPosts: function(page, pageSize) {
return $http.get("http://mywebservice/api/test/posts/" + page + "/" + pageSize);
}
};
});
Your controller
.controller('mainController', function($scope, dataService) {
$scope.posts = [];
$scope.theEnd = false;
var page = 0;
var pageSize = 10;
$scope.$on('$stateChangeSuccess', function() {
$scope.loadMore();
});
$scope.loadMore = function(argument) {
page++;
dataService.GetPosts(page, pageSize)
.then(function(result) {
console.log('items fetched: ' + result.data.length);
if (result.data.length > 0) {
angular.forEach(result.data, function(value, key) {
$scope.posts.push(value);
});
}
else {
$scope.theEnd = true;
}
})
.finally(function() {
$scope.$broadcast("scroll.infiniteScrollComplete");
});
};
})
would initialize an array of objetct - as you're doing - and a boolean which tells the directive ion-infinite-scroll when you've reached the end:
$scope.posts = [];
$scope.theEnd = false;
Then you can have some variables to control the pagination:
var page = 0;
var pageSize = 10;
I start loading when the view is loaded:
$scope.$on('$stateChangeSuccess', function() {
$scope.loadMore();
});
$scope.loadMore then would increment the page number:
page++;
and call the service layer:
dataService.GetPosts(page, pageSize)
when I've reached the end of the stream I would set the variable:
$scope.theEnd = true;
to let the directive know we don't have other items to append.
.finally(function() {
$scope.$broadcast("scroll.infiniteScrollComplete");
});
finally is always called when the promise is resolved.
Instead of ng-repeat you can use collection-repeat which should be much faster.
You can play with it here.
Try this create a function infiniteScrollCompleteCancelLoadMore and call it when you want to complete the scroll and you have reached the end of your list.
function infiniteScrollCompleteCancelLoadMore() {
$timeout(function () {
$timeout(function () {
$scope.$broadcast('scroll.infiniteScrollComplete');
$rootScope.canLoad = false;
});
});
}
$scope.loadMore = function() {
Worlds.GetNewPosts().then(function (worlds){
var loadedIdss = _.pluck($scope.worlds, 'id');
var newItemss = _.reject(worlds, function (item){
return _.contains(loadedIdss, item.id);
});
$scope.worlds = newItemss.concat($scope.worlds);
infiniteScrollCompleteCancelLoadMore() // CHANGE HERE
});
};
and your HTML
<ion-infinite-scroll on-infinite="loadMore()" ng-if="canLoad" distance="1%"
immediate-check="false"></ion-infinite-scroll>
OR call This is you just want to cancel loadMore loop.
function infiniteScrollComplete() {
$timeout(function () {
$timeout(function () {
$scope.$broadcast('scroll.infiniteScrollComplete');
});
});
}
In the following code, on autorefresh the timer starts when all the queries are sent, but I want the timer to start when all the ajax queries are completed.
How can I go about it?
$scope.autoRefresh = function(){
$scope.running = !$scope.running;
$scope.timeoutsec = 10;
if($scope.running)
{
$scope.timer = setInterval($scope.refresh, 10000);
$scope.count = $timeout($scope.countdown,1000);
}
else
{
clearInterval($scope.timer);
$timeout.cancel($scope.count);
}
}
countdown function --
$scope.countdown = function(){
$scope.timeoutsec = $scope.timeoutsec - 1;
$scope.count = $timeout($scope.countdown, 1000);
}
refresh function --
$scope.refresh = function(){
// update function
$scope.timeoutsec = 11;
}
Edit:
update function --
$scope.update() =function(){
for(var i=0;i<cluster.length;i++)
{
var request = $.ajax(cluster[i]).success(function(data, status, headers, config)
{
// on success
});
}
}
If you are using xmlhttp request, you have to set third parameter in xhr.open() function as true. This will make the request synchronous, shown below :
xhr.open(method, url, true);
Here is some boilerplate code for you to see how it could be done.
(function() {
'use strict';
angular.module('app')
.controller('controller', function($scope, $http, $timeout, $q) {
$scope.update = function () {
// single request
$http.get('url')
.then(function (data) {
$timeout($scope.update, 10000);
});
// or with multiple requests
var request1 = $http.get(/****/);
var request2 = $http.get(/****/);
var request3 = $http.get(/****/);
$q.all([request1, request2, request3])
.then(function() {
$timeout($scope.update, 10000);
});
};
});
})();
Initialise $scope.running to be false, only on the press of auto refresh button running should be set to true.
$scope.running = false;
autorefresh function -
$scope.autoRefresh = function(){
$scope.running = !$scope.running;
$scope.timeoutsec = 10;
if($scope.running)
{
$scope.count = $timeout($scope.countdown,1000);
}
else
{
$timeout.cancel($scope.count);
}
}
countdown function --
$scope.countdown = function(){
$scope.timeoutsec = $scope.timeoutsec - 1;
if($scope.timeoutsec == 0)
{
$scope.refresh();
}
whenAll($scope.queries).done(function(){
$scope.count = $timeout($scope.countdown, 1000);
});
refresh function ---
$scope.refresh = function(){
div.style.visibility = "visible";
$scope.update();
$scope.timeoutsec = 11;
}
whenall function --
function whenAll(promises) {
var i, data = [],
dfd = $.Deferred();
for (i = 0; i < promises.length; i++) {
promises[i].done(function(newData) {
data.push(newData);
if (data.length == promises.length) {
dfd.resolve(data);
}
}).fail(function() {
data.push("NO DATA");
if (data.length == promises.length) {
dfd.resolve(data);
}
});
}
return dfd.promise();
}
Push all your ajax queries to $scope.queries.
Push all your $http ajax into an array, like so, since $http return promises, youcan use the $q API to handle when all requests are finished:
var httpPromises = [
$http({method:'GET', url: '/myjson0.json'}),
$http({method:'GET', url: '/myjson1.json'}),
$http({method:'GET', url: '/myjson2.json'}),
$http({method:'GET', url: '/myjson3.json'})
];
//handle your requests like you would normally do
httpPromises[0].success(...).fail(...);
httpPromises[1].success(...).fail(...);
httpPromises[2].success(...).fail(...);
httpPromises[3].success(...).fail(...);
// remember to inject $q in your controller/factory
$q.all(httpPromises,function(){
//start your timer here
});
$q documentation
I have a particular function dependant on a (previously executed) service that will trigger multiple queries to a 3rd party API. This API with cancel the requests if it gets too many of them too quick. Is there a way to set a delay to the $http query?
Here is my $http code:
$scope.getImages = function (title, name) {
$http.get('http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=e8aefa857fc74255570c1ee62b01cdba&artist=' + name + '&album='+ title +'&format=json').
success(function(data4) {
$scope.images = data4;
});
}
EDIT Upon request I paste my whole JS (probably I should have done so from the start)
angular.module('myApp', ['ngResource'])
function Ctrl($scope, $http) {
var search = function(name) {
if (name) {
$http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=5').
success(function(data3) {
$scope.clicked = false;
$scope.results = data3.results;
});
}
$scope.reset = function () {
$scope.sliding = false;
$scope.name = undefined;
}
}
$scope.$watch('name', search, true);
$scope.getDetails = function (id) {
$http.get('http://api.discogs.com/artists/' + id).
success(function(data) {
$scope.artist = data;
});
$http.get('http://api.discogs.com/artists/' + id + '/releases?page=1&per_page=10').
success(function(data2) {
$scope.releases = data2.releases;
});
$scope.clicked = true;
$scope.sliding = true;
}
$scope.getImages = function (title, name) {
$http.get('http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=e8aefa857fc74255570c1ee62b01cdba&artist=' + name + '&album='+ title +'&format=json').
success(function(data4) {
$scope.images = data4;
});
}
};
I assume you will want to debounce your calls somehow, something simple like this should work. It will make the call every 300ms unless search(name) is called again before it fires.
var debounce = null;
var search = function(name) {
$timeout.cancel(debounce);
if (name) {
debounce = $timeout(function() {
$http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=5')
.success(function(data3) {
$scope.clicked = false;
$scope.results = data3.results;
});
},300);
}
$scope.reset = function () {
$scope.sliding = false;
$scope.name = undefined;
}
}
I am coding in angular js for client side pagination.
Starting in other question here about pagination, I've transformed the code to this but doesn't work.
What is wrong?
myapp.controller('MainCtrl', function($scope, Events) {
$scope.mydata = [];
Events.query(function(data) {
$scope.mydata = data;
});
$scope.get = function (offset, limit) {
return $scope.mydata.slice( offset, offset+limit );
};
$scope.count = function () {
return $scope.mydata.length;
};
$scope.numPerPage = 5;
$scope.noOfPages = Math.ceil($scope.count / $scope.numPerPage);
$scope.currentPage = 1;
$scope.setPage = function () {
$scope.data = $scope.get( ($scope.currentPage - 1) * $scope.numPerPage, $scope.numPerPage );
};
$scope.$watch( 'currentPage', $scope.setPage );
});
$scope.get and $scope.count don't work. Events.query is getting all JSON data from service in array format.
I can test this code in chrome angular js extension.
Any idea?
Use {{mydata.length}} in your html instead of the $scope.count function.