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

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.

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.

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!

how to unit test an angular.js service call using jasmine.js

It is a bit difficult for me to figure out the examples since I am a beginner could someone please help.
This is my code simple anjular.js service call
var app = angular.module('myApp', []);
var mycontroller = app.controller('Myctrl', function($scope, $http) {
$http.get("service.json")/*the json that i pass*/
.success(function(response) {$scope.names = response.records;});
});
I want to test this code using jasmine. What is the procedure and the code to do it.
You can use httpBackend mock service that will help to test your service.
Example-
describe('Myctrl', function() {
var $httpBackend, scope, createController, authRequestHandler;
// Set up the module
beforeEach(module('MyApp'));
beforeEach(inject(function($injector) {
// Set up the mock http service responses
$httpBackend = $injector.get('$httpBackend');
// backend definition common for all tests
authRequestHandler = $httpBackend.when('GET', 'service.json')
.respond(true);
// Get hold of a scope (i.e. the root scope)
$rootScope = $injector.get('$rootScope');
// The $controller service is used to create instances of controllers
var $controller = $injector.get('$controller');
createController = function() {
return $controller('MyController', {'$scope' : scope});
};
})
);
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should fetch authentication token', function() {
$httpBackend.expectGET('service.json');
var controller = createController();
expect(scope.names).toBe(true);
$httpBackend.flush();
});
});

AngularJS : get back data from a json array with an id

I have a json file where i am stocking informations from all the people in my database. I actually use it to display first name, last name in a web page and i want to add the possibility to display the details of every person.
To do so i'm using the id of the person like this :
.when('/people/:id', {templateUrl: 'partials/people-detail.html'})
It works pretty well, i have a page generated for every person, which is nice. But now I would like to get the information of the person back.
The easiest way would have been to have a json file for every person, but i don't particularly like the idea of having so much file.
So my actual idea is to iterate through the people.json file to find the good one and using it but it's not working.
Here's my controller :
var PeopleController = angular.module ('PeopleController', []);
PeopleController.controller('PeopleDetailCtrl', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
$scope.search = function() {
var url = 'data/people.json';
$http.get(url).success(httpSuccess).error(function() {
alert('Unable to get back informations :( ');
});
}
httpSuccess = function(response) {
$scope.persons = response;
}
function getById(arr, id) {
for (var d = 0, len = arr.length; d < len; d += 1) {
if (arr[d].id === id) {
return arr[d];
}
}
}
$scope.search();
$scope.person = getById($scope.persons,$routeParams.id);
}]);
Well, maybe my solution is bad since it doesn't work, but i didn't find another way to do so.
Now i'm all yours :)
Thanks for reading.
The problem is that your $scope.search method contains $http.get() which is asynchronous.
What that means is your next line (the one that sets $scope.person) executes before the json file has been read. As such, $scope.persons is empty at the time it is executed.
You can take advantage of the fact that $http.get() returns a chainable promise here.
So if you change your search() function to return that promise, you can then use then() to populate person when everything has been successful:
$scope.search = function() {
var url = 'data/people.json';
return $http.get(url).success(httpSuccess).error(function() {
alert('Unable to get back informations :( ');
});
}
(note the return statement).
Then change the person population to take advantage of this:
$scope.search().then(function(){
$scope.person = getById($scope.persons,$routeParams.id);
});
I hope getting a person is a whole different event like on click. You can try grep:
$scope.person = function(_id) {
return $.grep($scope.persons, function(item){
return item.id == _id
})[0];
}
Assuming you have all persons available otherwise this logic has to move inside the part of the success callback for the http call.
I used ECMAScript 5 filter to get person by id and moved your search by id to success method since we are dealing with ajax call.
Example:
app.controller('PeopleDetailCtrl', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
$scope.search = function() {
var url = 'data.json';
$http.get(url).success(httpSuccess).error(function() {
alert('Unable to get back informations :( ');
});
}
httpSuccess = function(response) {
$scope.persons = angular.fromJson(response);
$scope.person = $scope.persons.filter(function(item){
return item.id==routeParams.id //check for undefined;
});
}
$scope.search();
}]);
Live Example: http://plnkr.co/edit/jPT6aC5UqLdHGJ1Clfkg?p=preview

Update fields with user position using a service

I would like to update some fields when I receive a geoposition for a give user.
Until know I have the following code:
http://jsfiddle.net/VSph2/10/
Firstly, I get a Error: Unknown provider: positionProvider <- position (only on jsfiddle). I do not get this error on my real site.
The problem is that when I get the position I update the position object in the service but it does not update in the HTML view.
Any suggestions?
Try this. Fiddle
var test = angular.module('myApp', []);
var services = angular.module('myApp.services', []);
services.factory('position', ['$http', function ($http) { ...
should be
var test = angular.module('myApp', []);
test.factory('position', ['$http', function ($http) { ...
You should update the controller code as this, to use a callback function and $apply to apply the value set to the scope.
position.getPosition(function (p) {
$scope.$apply(function () {
$scope.position.latitude = p.coords.latitude;
$scope.position.longitude = p.coords.longitude;
$scope.position.accuracy = p.coords.accuracy;
});
});