give random order to $http json oject through angular JS controller - json

I pull in a JSON object with my controller below, but how do I make the order random, on each page refresh?
app.controller('MainCtrl', ['$scope', '$http', 'makeRandom', function ($scope, $http, makeRandom) {
$http.get('projects/projects.json').success(function(data) {
$scope.works = data;
});
makeRandom.forEach($scope.works, function(work) {
work.rank = Math.random();
});
}]);
template.html
<section ng-repeat="work in works | orderBy:'rank'" class="showcase {{work.class}}">
...
</section>

You pretty much have all the work done, you just need to put it together:
This is based off your work:
app.controller('myCtrl', ['$scope', '$http', function($scope, $http){
$http.get('projects/projects.json').success(function(data) {
$scope.works = data;
}).error(function(){
// works on error response because I don't have your code, just copy this to success response
// here I just generate a list of ids and then randomize them
var works = [];
for(var i=0; i< 20; i++){
works.push({id: i});
}
$scope.works = makeRandom(works);
});
function makeRandom(inputArray){
angular.forEach(inputArray, function(value){
value.rank = Math.random();
});
return inputArray;
}
}]);
HTML:
<section ng-repeat="work in works | orderBy:'rank'" class="showcase {{work.class}}">
{{work.rank}} {{work}}
</section>
Here is a working example: http://plnkr.co/edit/xIwD0zWdodnYSIupm1va?p=preview

Related

Trying to import data from JSON file, and displaying in HTML

Here's the script I'm using :
(function() {
var app = angular.module("myQuiz", []);
app.controller('QuizController', ['$scope', '$http', '$sce', function($scope, $http, $sce){
$scope.score = 0;
$scope.activeQuestion = -1;
$scope.activeQuestionAnswered = 0;
$scope.percentage = 0;
$http.get('quiz_data.json').then(function(quizData){
$scope.myQuestions = quizData.data;
$scope.totalQuestions = $scope.myQuestions.length;
});
}])
})
After this, I'm trying to display the 'total questions' on my HTML using {{totalQuestions}} but instead of showing the number of questions, it just displays {{totalQuestions}} as it is.
You have this in code:
(function() {
var app = angular.module("myQuiz", []);
// ..
})
But this will never actually execute the function, so your module won't be defined.
Just add the () at the end:
(function() {
var app = angular.module("myQuiz", []);
// ..
}())
Try renaming <div id="myQuiz"> to something else it can not be same as ng-app="myQuiz" and define your scope variable inside <div id="myQuizId" ng-controller = 'QuizController'> {{hereYourVariable}} </div>
Add these things in your index.html file :
ng-app = "myQuiz",
ng-controller="QuizController" if required,
add reference to your angular js cdn or its script file
then below angular cdn/script reference add your script file reference.

Cannot read property 'toLowerCase' of undefined angularjs

I'm trying to make a search function in my angularjs "webapp". When I search in products all works fine, but when I change everything so that it searches into users, i get an error Cannot read property 'toLowerCase' of undefined.
Here's my js:
return function(arr, searchString){
if(!searchString){
return arr;
}
var result = [];
searchString = searchString.toLowerCase();
angular.forEach(arr, function(item){
if(item.title.toLowerCase().indexOf(searchString) !== -1){
result.push(item);
}
});
return result;
};
});
And here's the html that's calling it:
<div ng-controller="userCtrl" class="container-app">
<div class="bar">
<input type="text" class="search" ng-model="searchString" placeholder="Enter your search terms" />
</div>
<div class="searchResultsText">
<h2>Zoekresultaten: </h2>
</div>
<div class="searchResults" ng-repeat="user in users | searchFor:searchString">
<a class="normal" href="#">{{user.name}}</a>
</div>
it does show me the list of users, just as soon as I start typing in the search bar it gives me the error.
when I use the exact same function, with a different controller it works. Here are the 2 controllers:
app.controller('customersCtrl', function ($scope, $http) {
$http.get(apiUrl + "product/list")
.success(function (response) {
$scope.products = response;
});
});
app.controller('userCtrl', function ($scope, $http) {
$http.get(apiUrl + "user/list")
.success(function (response) {
$scope.users = response;
});
});
so basically customerCtrl works fine, but when i change values to userCtrl it stops working.
any suggestions?
Most likely item.title is at least once undefined.
return function(arr, searchString){
if(!searchString){
return arr;
}
var result = [];
searchString = searchString.toLowerCase();
angular.forEach(arr, function(item){
if(
angular.isDefined(item.title) &&
item.title.toLowerCase().indexOf(searchString) !== -1
){
result.push(item);
}
});
return result;
};

AngularJS: Loading single objects from json

I'm trying to list some posts from a json file then after click one, load the single post, but when I click it the data is not loaded.
I'm using the function below to handle the data
$scope.currentPost = $filter('filter')($scope.posts, {id: $routeParams.id})
Here is my Plnkr: http://plnkr.co/edit/brWn6r4UvLnNY5gcFF2X?p=preview
Updated Plnkr: http://plnkr.co/edit/3P2k60aPyuatjTx9raJU?p=preview
app.controller('MainCtrl', function($scope, $http, $route, $routeParams, $filter) {
$scope.name = 'Test';
$scope.getData = function(){
$http.get('posts.json')
.then(function(res){
$scope.posts = res.data.posts;
$scope.currentPost = $filter('filter')($scope.posts, {id: $routeParams.id});
$scope.currentPost = $scope.currentPost[0]; // $filter apparently returns an array...
});
};
// setInterval($scope.getData, 1000); // DO WE REALLY NEED IT?
$scope.getData();
});
Alternative solution using _ (underscore) findWhere method:
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
app.controller('MainCtrl', function($scope, $http, $route, $routeParams, $filter) {
$scope.name = 'Test';
$scope.getData = function(){
$http.get('posts.json')
.then(function(res){
$scope.posts = res.data.posts;
// id: integer
// $routeParams.id: string
// when comparing integer to string _.findWhere was failing
// always good practice to pass radix to parseInt: http://davidwalsh.name/parseint-radix
$scope.currentPost = _.findWhere($scope.posts, {id: parseInt($routeParams.id, 10)});
});
};
// setInterval($scope.getData, 1000); // DO WE REALLY NEED IT?
$scope.getData();
});
Plnkr: http://plnkr.co/edit/N7UeaOuoNIoQgzQfrkY3?p=preview
In my code I usually use _ but now I've learnt something new - I can use $filter too!

Angular service not storing data between two controllers

I am trying to use a service to set title in controller1 and then access title in controller2.
sharedProperties.setTitle(title) works in controller1, but when I try to get the title in controller2, it gets "title" (the initial value) instead of the new value.
I've also tried storing title in an object but it didn't work.
app.service('sharedProperties', function () {
var title = "title"
return {
getTitle: function () {
return title;
},
setTitle: function (val) {
title = val;
}
}
});
app.controller('controller1', ['$scope', 'sharedProperties', function ($scope, sharedProperties) {
$('body').on("click", "button[name=btnListItem]", function () {
// gets the title
var title = $(this).text();
// sets the title for storage in a service
sharedProperties.setTitle(title);
});
}]);
app.controller('controller2', ['$scope', 'sharedProperties', function ($scope, sharedProperties) {
$scope.sharedTitle = function() {
return sharedProperties.getTitle();
};
}]);
And in my view, I have {{ sharedTitle() }} which should, as I understand it, update the title text with the new title.
Also, in case this is relevant: the two controllers are linked to two different html pages.
What am I doing wrong?
EDIT
Updated button listener:
$('body').on("click", "button[name=btnListItem]", function () {
// gets the text of the button (title)
var title = $(this).text();
sharedTitle(title);
alert(sharedProperties.getTitle());
document.location.href = '/nextscreen.html';
});
$scope.sharedTitle = function (title) {
sharedProperties.setTitle(title);
};
It seems to be correct in your sample code. I setup jsfiddle and it seems work correctly. Finding out a difference between my jsfiddle and your actual code would help you to find the problem you should solve.
Javascript:
angular.module('testapp', [])
.service('sharedProperties', function(){
var title = 'title';
return {
getTitle: function(){
return title;
},
setTitle: function(val){
title = val;
}
};
})
.controller('controller1', function($scope, sharedProperties){
$scope.change_title = function(newvalue){
sharedProperties.setTitle(newvalue);
};
})
.controller('controller2', function($scope, sharedProperties){
$scope.sharedTitle = function(){
return sharedProperties.getTitle();
};
})
Html:
<div ng-app="testapp">
<div ng-controller="controller1">
<input ng-model="newvalue">
<button ng-click="change_title(newvalue)">Change Title</button>
</div>
<div ng-controller="controller2">
<span>{{sharedTitle()}}</span>
</div>
</div>
My jsfiddle is here.
You have to print console.log(sharedProperties.getTitle()); Dont need return from controller.
So your code of controller2 is $scope.sharedTitle = sharedProperties.getTitle();
You need to use the $apply so that angular can process changes made outside of the angular context (in this case changes made by jQuery).
$('body').on("click", "button[name=btnListItem]", function () {
// gets the title
var title = $(this).text();
// sets the title for storage in a service
$scope.$apply(function() {
sharedProperties.setTitle(title);
});
});
See plunker
That said, this is BAD PRACTICE because you're going against what angular is meant for. Check “Thinking in AngularJS” if I have a jQuery background?. There are cases when you need to use $apply like when integrating third party plugins but this is not one of those cases.

How to load a JSON data Object from other domain (no callback function) with AngularJS

Is it possible to load JSON data without callback function in AngularJS? If I manually download the json file and change the url to 'phones/phones.json'. In jQuery it is possible http://www.sitepoint.com/jsonp-examples/
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get('https://raw.githubusercontent.com/angular/angular-phonecat/master/app/phones/phones.json').success(function(data) {
$scope.phones = data.splice(0, 5);
});
$scope.orderProp = 'age';
}]);
SOLVED: Thanks! I changed "raw.githubusercontent.com/angular/angular-phonecat/master/app/phones/phones.json" to "rawgit.com/angular/angular-phonecat/master/app/phones/phones.json"
See https://rawgit.com/faq
It was server side problem as Words Like Jared said.
The problem is not with your client but with your server.
http://plnkr.co/edit/a7K79KTae3CPPZx7XMfH?p=preview
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get('https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS').success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
}]);
That's virtually the same code pointed to a different URL and it works.
I think you need the HTTP request's response to contain the "Access-Control-Allow-Origin" header with a value of say "*" to access the content from another site. How to do that will vary depending on your server technology.