how to use JSONP in AngularJS resource - json

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....

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.

Angularjs and Web Services

I make a web services which returns me a JSON formatted data when I use this url(http://localhost:8080/jerseyweb/crunchify/ftocservice). Now I want to get those data through Angular js but I can not get it. The code with which I try that is as follow:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<ul>
<li ng-repeat="x in names">
{{ x.id + ', ' + x.name }}
</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
alert("hi");
$http.get("http://localhost:8080/jerseyweb/crunchify/ftocservice")
.success(function (data, status, headers, config) {
alert("hiee"); // i can not reach at this alert
$scope.names = data;
});
});
</script>
</body>
</html>
The JSON data in http://localhost:8080/jerseyweb/crunchify/ftocservice is as following
[{"id":98.24,"name":36.8}]
There is an error in Web Services Response.....
#OPTIONS
#Path("/getsample")
public Response getOptions() {
return Response.ok()
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, OPTIONS")
.header("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With")
.build();
}
Please try this code might be it's use full :
var response = $http({
method: "GET",
url: "http://localhost:8080/jerseyweb/crunchify/ftocservice",
dataType: "json"
});
response.then(function (obj) {
$scope.names = obj.data.name;
}, function () {
alert('Error.');
});
If data comes from the API in string format then use
var objdata = JSON.parse(obj.data);
$scope.names = objdata.name;

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 is possible to load some setting from .json file before angular app starts

i'm building application which uses CORS requests. Each request i use get host address from a constant
angular.module('siteApp').constant('baseUrl', {
'server':'htttp://localhost/',
})
And in each service i use to send request like this:
angular.module('siteApp').factory('DocsSvc', function ($http, baseUrl) {
var baseurl = baseUrl.server ;
$http.get(baseurl + 'document')
Is it possible to make 'htttp://localhost/' value - to came from config.json file into baseUrl constant or baseUrl factory?
I mean : how can i load something from ajax request an make it accessible to app modules
i have tried:
.run(['$rootScope', , function ($rootScope) {
$.ajax('config.json', {async: false})
.success(function (data) {
$rootScope.HOST = data.HOST;
});
And tried to access it from baseUrl:
angular.module('siteApp').factory('baseUrl',function($rootScope) {
return {
server: $rootScope.HOST
But no luck - the baseUrl.server comes undefined into functions
You can use run method of angular.
var app = angular.module('plunker', []);
app.run(function($http, $rootScope){
$http.get('config.json')
.success(function(data, status, headers, config) {
$rootScope.config = data;
$rootScope.$broadcast('config-loaded');
})
.error(function(data, status, headers, config) {
// log error
alert('error');
});
})
app.controller('MainCtrl', function($scope, $rootScope) {
$scope.$on('config-loaded', function(){
$scope.name = $rootScope.config.name;
});
});
see this plunker
If you want to do it even before the angular app starts, you can, instead of using the ng-app directive, use the bootstrap function.
From:
https://docs.angularjs.org/api/ng/function/angular.bootstrap
<!doctype html>
<html>
<body>
<div ng-controller="WelcomeController">
{{greeting}}
</div>
<script src="angular.js"></script>
<script>
var app = angular.module('demo', [])
.controller('WelcomeController', function($scope) {
$scope.greeting = 'Welcome!';
});
// Do your loading of JSON here
angular.bootstrap(document, ['demo']);
</script>
</body>
</html>
You need to tell angular about data change, so modify your code something like this:
.run(['$rootScope', function ($rootScope) {
$.ajax('config.json', {async: false})
.success(function (data) {
$rootScope.HOST = data.HOST;
$rootScope.$apply(); // New line
});
}])
That $apply() is needed since its a non-angular asynchronous call.
use the blow code snippet to load the json values
.run(function ($http, $rootScope) {
$http.get('launchSettings.json')
.success(function (data, status, headers, config) {
$rootScope.config = data;
$rootScope.$broadcast('config-loaded');
})
.error(function (data, status, headers, config) {
// log error
alert('error');
});
});