Fetch the external json file through Angular JS - json

I have try to fetch the json data by using Angular JS. I have successfully fetch through static json data. But now I have try to fetch through external JSON file. Below is my code & there output :
index.html
<!doctype html>
<html ng-app="MyInfo">
<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="js/controllers.js" type="text/javascript" ></script>
</head>
<body>
<div ng-controller="MyInfoFunction">
<ul>
<li ng-repeat="item in myinfoVariable">
<div>
<h3> {{item.name }}</h3>
<p> {{item.city}}</p>
<p> {{item.state}}</p>
</div>
</a>
</li>
</div>
</body>
</html>
data.json - js/data.json
[
{
"name" : "myname1",
"city": "mycity1",
"state" : "mystate2"
},
{
"name" : "myname2",
"city": "mycity2",
"state" : "mystate2"
},
{
"name" : "myname3",
"city": "mycity3",
"state" : "mystate3"
}
]
controllers.js : js/controllers.js
var nameSpace = angular.module("MyInfo", []);
nameSpace.controller("MyInfoFunction", function MyInfoFunction($scope, testService) {
function Init() {
$scope.data = {};
testService.getData().then(function(data) {
console.log(data)
});
}
Init();
});
nameSpace.service('testService', function ($http) {
this.getData = function () {
return $http.get('js/data.json');
}
});
Output :
{{item.name }}
{{item.city}}
{{item.state}}
I have try to fetch but unable to get the data. What am I doing wrong please help.

your controller is messy and incorrect, extra } & )
nameSpace.controller("MyInfoFunction", function MyInfoFunction($scope, testService) {
function Init() {
$scope.data = {};
testService.getData().then(function(data) {
$scope.myinfoVariable = data.data;
// console.log(data)
});
}
Init();
});
your .json should be like
[
{"name":"a","city":"b","state":"c"},
{"name":"x","city":"y","state":"z"}
]
if your data.json file is in inside of the js folder then the getting json should be like
this.getData = function () {
return $http.get('js/data.json');
}

You should try to get js/data.json instead of data.json.
nameSpace.service('testService', function ($http) {
this.getData = function () {
return $http.get('js/data.json');
}
});
You need to provide the url relative to your index.html.
If you are hosting your application on http://myapp.com, and the json file you need to get is hosted on http://myapp.com/js/data.json then you can either do $http.get("js/data.json") either $http.get("http://myapp.com/js/data.json").
However, if your json file is hosted on another website, let's say http://mysecondapp.com, then you need to do $http.get("http://mysecondapp.com/data.json")

Related

How to add JSON object into JSON array using angular JS?

I have problem while parsing single json object.
Assume that the below data get from server
{
"root": {
"data": [
{
"name": "Raj",
"age": "22"
},
{
"name": "Janu",
"age": "22"
}
]
}
}
And my script is
Script.js
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl', function($scope, $http){
$http.get("manydata.json")
.success(function(response) {
$scope.myDatas = response.root;
});
});
HTML
<div ng-repeat="i in myDatas.data">
Name: {{i.name}}
Age: {{i.age}}
</div>
I have no problem while the response data is more than 1. But If the response data is 1 then the json will be:
{
"root": {
"data": {
"name": "Raj",
"age": "22"
}
}
}
How to generically parse these json data ?
PLNKR: http://plnkr.co/edit/W4YK6BDtIBfVhnPpHVm1?p=preview
You need just slight change, check type of responsedata.root.data. If it is not array, convert it to array. Here is your code becomes.
Here is plnkr
// Code goes here
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl', function($scope, $http){
$http.get("singledata.json")
.success(function(response) {
if(response.root.data && !(response.root.data instanceof Array )){
response.root.data=[response.root.data]
}
$scope.myDatas = response.root;
});
});
You can normalize incoming data to always be an array. It's convenient to use Array.prototype.concat method for this:
$http.get("singledata.json")
.success(function(response) {
$scope.myDatas = response.root;
$scope.myDatas.data = [].concat($scope.myDatas.data);
});
Demo: http://plnkr.co/edit/UUWtDBK8qID1XoYeMXhu?p=preview
I would check if data is an array or not, and if not, just ammend the data to be an array:
Like this:
$http.get("singledata.json")
.success(function(response) {
if(response.root.data && !angular.isArray(response.root.data)){
var object = response.root.data;
response.root.data = [];
response.root.data.push(object);
}
$scope.myDatas = response.root;
});
You can check the whether the data is array or not. If not then you create the array as. Check this code its working.
For controller:
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl', function($scope, $http){
$http.get("manydata.json")
.success(function(response) {
var data = response.root.data;
if(data.constructor === Array){
$scope.myDatas = data;
}else{
$scope.myDatas = new Array(data);
}
});
});
For html:
<div ng-repeat="i in myDatas">
Name: {{i.name}}
Age: {{i.age}}
</div>
Hope this helps.

Add sort to Angular factory

I want to add a sort function to my factory controller in Angular JS.
I have got as far as what I have below:
var albumsApp = angular.module ('albumsApp',[])
albumsApp.factory('albumFactory',function($http) {
return {
getAlbumsAsync: function(callback,$scope){
$http.get('albums.json').success(callback);
},
};
});
albumsApp.controller ('albumController', function ($scope,albumFactory) {
albumFactory.getAlbumsAsync(function(results){
console.log('albumController async returned value');
$scope.albums = results.albums;
});
albumFactory.changeSorting(function(results){
console.log('changeSorting called');
});
});
I get an error "TypeError: albumFactory.changeSorting is not a function" (this refers to the albumFactory.changeSorting) as I have not added it to the factory. I don't know how to do this.
The html code I am using is below: I want to call the function to sort what is in the JSON file alphabetically
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="js/angular.js"></script>
<script src="js/angular-route.js"></script>
<script type="text/javascript" src="modules/app.js" ></script>
</script>
<title>
</title>
</head>
<body ng-app="albumsApp">
<div data-ng-controller="albumController">
<!-- <ul data-ng-repeat="album in albums| orderBy:'title'"> -->
<ul data-ng-repeat="album in albums">
<li>
Artist is "{{album.artist}}" and title is "{{album.title}}"
</li>
</ul>
<button data-ng-click="changeSorting()">Description</button>
</div>
</body>
</html>
The JSON list is below:
{
"albums":[
{
"artist": "Arctic Monkeys",
"title": "AM"
},
{
"artist": "Nirvana",
"title": "Nevermind"
},
{
"artist": "Buck 65",
"title": "Man Overboard"
}
]
}
Your view is not directly connected to the Angular service—all methods called from the view should be in your controller. You should have a method on your controller and not in your factory. Try moving that function to your controller:
albumsApp.controller ('albumController', function ($scope,albumFactory) {
albumFactory.getAlbumsAsync(function(results){
console.log('albumController async returned value');
$scope.albums = results.albums;
});
$scope.changeSorting = function (){
// your logic goes here
console.log('changeSorting called');
});
});
You can keep your logic in your controller. You can use orderBy in Angular's $filter module to help you sort:
$filter('orderBy')(array, expression, reverse)

How to access to element of json file in local host?

I need to select an element from my data with my $resource, but I have this error :
"Error: $produit1 is not defined GET XHR
http://localhost:8080/Jquery/data/produits.json/1 [HTTP/1.1 404
Introuvable 15ms]
I Think the problem comes from this url: http://localhost:8080/Jquery/data/produits.json/1
because this url http://localhost:8080/Jquery/data/produits.json is OK when i put it on my browser i can see the data, the first dont show me the data (Etat HTTP 404 - /Jquery/data/produits.json/1 )
[
{
"id" : 1,
"reference": "AAA",
},
{
"id" : 2,
"reference": "BBB",
}
]
How can I call my elements by the url please ?
Here is my code :
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Angular ngResource</title>
<script src= "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-resource.min.js"></script>
<script>
var myApp = angular.module('myApp', ['ngResource']);
myApp.factory('Produits',['$resource', function ($resource) {
return $resource('data/produits.json/:id',{id: "#id"},
{
'update': {method: 'PUT'},
'reviews': {method: 'GET'}
}
);
}]);
myApp.controller('produitsCtrl', function($scope, $http,Produits,$log) {
$scope.produits= Produits.query();
$scope.produit1 = Produits.get({'id': 1});
});
</script>
</head>
<body>
<div ng-app="myApp" >
<div ng-controller="produitsCtrl">
Reference 1 : {{ produit1.reference }}
</div>
</div>
</body>
</html>
The thing is that your call :
$resource('data/produits.json/:id',{id: "#id"},
is looking for a json that is generated regarding the id you pass. So your app expects to have a json file that exists only if in your route id=1 exists and returns a json.
$scope.produit1 = Produits.get({'id': 1});
should return a json file with elements as the ones you have currently.
If you want to use the datas contained in your json you need to do this :
var Produits = $resource(data/produits.json);
myApp.controller('produitsCtrl', function($scope, $http,Produits,$log) {
var upd = {
"id": 1,
"reference": "REF"
}
Produits.$update(upd.id);
});

Displaying nested JSON with angularjs

I am trying to display nested JSON in a page. I'm not sure how to drill down into it.
In my app js file I have an parameter called initialData that I want to call a function getProducts() when the view is called...
'use strict';
var quoteApp = angular.module('quoteApp', ['ui.router']);
quoteApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'ng-views/choose.html',
controller: "quoteBuilderController",
resolve: {
initialData: ['quoteApi', function (quoteApi) {
return quoteApi.getProducts();
}]
}
})
});
my quoteApi looks like this in case you want to see it...
(function () {
'use strict';
angular.module('quoteApp').factory('quoteApi', quoteApi);
quoteApi.$inject = ['$http'];
function quoteApi($http) {
var service = {
getProducts: getProducts,
getPrices: getPrices
};
var baseUrl = 'http://www.website.com/api/Pricing';
return service;
function getProducts() {
return httpGet('/GetProductCatalogue');
}
function getPrices() {
return httpGet('/GetPrices');
}
/** Private Methods **/
function httpExecute(requestUrl, method, data){
return $http({
url: baseUrl + requestUrl,
method: method,
data: data,
headers: requestConfig.headers }).then(function(response){
return response.data;
});
}
function httpGet(url){
return httpExecute(url, 'GET');
}
}
})();
So quoteApi.getProducts() returns JSON that looks like this...
{
"Cat1": [
{
"product_id": 1,
"product_name": "Prod1"
},
{
"product_id": 2,
"product_name": "Prod2"
}
],
"Cat2": [
{
...
}
]
}
My controller for the view looks like this...
(function () {
'use strict';
angular.module('quoteApp').controller('quoteController', ['$scope', '$http', '$timeout', quoteController]);
quoteController.$inject = ['initialData', 'quoteApi'];
function quoteController($scope, initialData) {
$scope.cat1Products = initialData;
};
})();
So my question is, how can I get 'initialData' to load products from Cat1 only? Should I try to do this from the html? It seems like it should be straight forward enough but I can seem to get it. Thank you.
You need to transform your response from your http request further so you only return the piece you require, and you may also want to consider using the .then() approach:
$http.get('/someUrl').then(function(response) {
//Do something with response.data.Cat1 here
}, function(errResponse) {
console.error('Error while fetching data');
});
Just take out cat1 from your initialData object
function quoteController($scope, initialData) {
$scope.cat1Products = initialData['Cat1'];
};

how to use JSONP in AngularJS resource

I'm trying to import json object into variable. I use the services according to tutorial.
I receive unexpected token error, because i shouldn't use $scope.news = JsonSource.feed(); - but I really don't know what should I use. I googled and searched 3 hours I find only $http. or $json. answers, but I feel, that it could be done easier - clearer.
(The perfect solution would be $scope.news = JsonSource.feed().entries ;D
The services file:
var AAAServices = angular.module('AAAServices', [
'ngResource'
]);
AAAServices.factory('JsonSource', ['$resource',
function($resource) {
return $resource('https://www.facebook.com/feeds/page.php', {}, {
feed: {method:'JSONP', {format: 'json', id:'459908', callback : JSON_CALLBACK}, isArray:false}
});
}]);
The controllers file:
var AAAControllers = angular.module('AAAControllers', [])
AAAControllers.controller('newsCtrl', ['$scope', 'JsonSource',
function newsCtrl($scope, JsonSource) {
$scope.news = JsonSource.feed();
}]);
the json file (almost ;D)
{
"title": "Tytuł",
"link": "https:\/\/www.facebook.com\/",
"entries": [
{
"title": " news 1",
"id": "1"
},
{
"title": " news 2",
"id": "2"
}
]
}
Edited:
i change $resource('file.json into https://www.facebook.com/feeds/page.php - so you can check if it is json or jsonp...
I did not notice that it takes to be a JSONP, so I did it with default $resource method.
Below is an example that does what you want.
Please remember to:
include a file angular-resource.min.js
inject ngResource to services module
inject motoAdsServices to app module
inject Brand to controller
the rest will do Angular :)
index.html
<!DOCTYPE html>
<html ng-app="motoAdsApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.min.js"></script>
<script type="text/javascript" src="controllers.js"></script>
<script type="text/javascript" src="services.js"></script>
</head>
<body>
<div ng-controller="AdvertsController">
<label>Brand</label>
<select name="brand" ng-model="brand" ng-options="b.name for b in brands">
<option value=""></option>
</select>
</div>
</body>
</html>
services.js
var motoAdsServices = angular.module('motoAdsServices', ['ngResource']);
motoAdsServices.factory('Brand', ['$resource', function($resource) {
return $resource('./brands.json', {}, {});
}]);
controllers.js
var motoAdsApp = angular.module('motoAdsApp', ['motoAdsServices']);
motoAdsApp.controller('AdvertsController', ['$scope', 'Brand',
function($scope, Brand) {
$scope.brands = Brand.query();
}]);
brands.json
[
{"name": "Audi", "models": [{"name": "A1"}, {"name": "A3"}, {"name": "A4"}]},
{"name": "BMW", "models": [{"name": "Series 3"}, {"name": "Series 5"}, {"name": "Series 7"}]},
{"name": "Citroen", "models": [{"name": "C1"}, {"name": "C2"}, {"name": "C3"}]},
{"name": "Dacia", "models": [{"name": "Duster"}, {"name": "Logan"}, {"name": "Sandero"}]}
]
Plunker example
UPDATE (because should be JSONP)
To use JSONP you should only change services.js
var motoAdsServices = angular.module('motoAdsServices', ['ngResource']);
motoAdsServices.factory('Brand', ['$resource', function($resource) {
return $resource('./brands.json', {}, {
jsonpquery: { method: 'JSONP', params: {callback: 'JSON_CALLBACK'}, isArray: true }
});
}]);
and controllers.js
var motoAdsApp = angular.module('motoAdsApp', ['motoAdsServices']);
motoAdsApp.controller('AdvertsController', ['$scope', 'Brand',
function($scope, Brand) {
$scope.brands = Brand.queryjsonp();
}]);
And it shoould be work. But server should return valid jsonp.
There is the same problem:
jsonp request with angular $resource
And he found that there was a problem with server.
UPDATE 2 (because the problem is probably with CORS in node.js server)
server.js (node.js)
var express = require('express');
var path = require('path');
var http = require('http');
var brands = require('./routes/brands');
var countries = require('./routes/countries');
var adverts = require('./routes/adverts');
var app = express();
// ALLOW CORS!!!
var allowCrossDomain = function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
};
app.configure(function() {
app.set('port', process.env.PORT || 3000);
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser()),
app.use(allowCrossDomain);
app.use(express.static(path.join(__dirname, 'public')));
});
app.get('/api/brands', brands.findAll);
app.get('/api/countries', countries.findAll);
app.get('/api/adverts', adverts.findAll);
http.createServer(app).listen(app.get('port'), function() {
console.log("Express server listening on port " + app.get('port'));
});
routes/brands.js
exports.findAll = function(req, res) {
var fs = require('fs');
var file = './server/data/brands.json';
fs.readFile(file, 'utf8', function(err, data) {
if (err) {
throw err;
}
res.send(JSON.parse(data));
});
};
UPDATE 3 (because CORS should be added to web-server.js (node.js) without express)
You have something like:
https://github.com/angular/angular-seed/blob/master/scripts/web-server.js
So you have to add ALLOW CORS (look below I added 2 lines) to response headers:
StaticServlet.prototype.sendFile_ = function(req, res, path) {
var self = this;
var file = fs.createReadStream(path);
res.writeHead(200, {
'Content-Type': StaticServlet.
MimeMap[path.split('.').pop()] || 'text/plain',
// ALLOW CORS - line 1 !!!
'Access-Control-Allow-Origin' : '*',
// ALLOW CORS - line 2 !!!
'Access-Control-Allow-Headers': 'X-Requested-With'
});
if (req.method === 'HEAD') {
res.end();
} else {
file.on('data', res.write.bind(res));
file.on('close', function() {
res.end();
});
file.on('error', function(error) {
self.sendError_(req, res, error);
});
}
};
Maybe you have other function with jsonp, so add to res.writeHead(200, CORS headers too.
UPDATE 4 - ANGULARJS CALL FACEBOOK BY JSONP
THIS SOLUTION SHOULD BE WORK !!!
services.js
var myServices = angular.module('myServices', ['ngResource']);
myServices.factory('FacebookFeed', ['$resource',
function($resource) {
return $resource('https://graph.facebook.com/cocacola?callback=JSON_CALLBACK', {}, {
jsonp_query: {
method: 'JSONP'
}
});
}
]);
controllers.js
var myApp = angular.module('myApp', ['myServices']);
myApp.controller('MyController', ['$scope', 'FacebookFeed',
function($scope, FacebookFeed) {
$scope.feeds = FacebookFeed.jsonp_query();
console.log()
}]);
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.min.js"></script>
<script type="text/javascript" src="controllers.js"></script>
<script type="text/javascript" src="services.js"></script>
</head>
<body>
<div ng-controller="MyController">
<label>Facebook feeds</label></label>
<pre>{{feeds}}</pre>
</div>
</body>
</html>
Plunker example
This is the answer for those, who thinks (as me) that if something works in browser it should work in server scripts.
facebook gives very nice json for the wall content:
https://www.facebook.com/feeds/page.php?format=json&id=xxxx
But you can't get it from nodejs - because of cross domain policy-restriction
More about is here: Loading facebook wall feed JSON issues
So, now i have to search for jsonp stream for facebook wall... Sigh....