6

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

2 Answers 2

8

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

Sign up to request clarification or add additional context in comments.

13 Comments

unfortunately the json is on outside server, so the Access-Control-Allow-Origin problem appears... I found that the best solution is to use jsonp
Look at my update maybe it help you. When Access-Control-Allow-Origin problem apears. Your server should allow CORS request.
this is exactly what I set - i found no difference. But how to check if server returns valid jsonp?
What about CORS your server allow it? For example in node.js server you should do res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "X-Requested-With"); to allow CORS. So maybe problem is not with Angular but with server.
I have just looked at your updated resource url in your answer. I think that server https://www.facebook.com/feeds/page.php should response CORS headers yet. Why you use angular-seed web-script.js if you call https://www.facebook.com/feeds/page.php?
|
-3

This is the answer for those, who thinks (as me) that if something works in browser it should work in server scripts.

  1. facebook gives very nice json for the wall content:

https://www.facebook.com/feeds/page.php?format=json&id=xxxx

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.