Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: factory $http.get JSON file

I am looking to develop locally with just a hardcoded JSON file. My JSON file is as follows (valid when put into JSON validator):

{     "contentItem": [             {             "contentID" : "1",              "contentVideo" : "file.mov",             "contentThumbnail" : "url.jpg",             "contentRating" : "5",             "contentTitle" : "Guitar Lessons",             "username" : "Username",              "realname" : "Real name",             "contentTags" : [                 { "tag" : "Guitar"},                 { "tag" : "Intermediate"},                 { "tag" : "Chords"}             ],                   "contentAbout" : "Learn how to play guitar!",             "contentTime" : [                 { "" : "", "" : "", "" : "", "" : ""},                 { "" : "", "" : "", "" : "", "" : ""}             ],                       "series" :[                 { "seriesVideo" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "1", "seriesTitle" : "How to Play Guitar" },                 { "videoFile" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "2", "seriesTitle" : "How to Play Guitar" }             ]         },{             "contentID" : "2",              "contentVideo" : "file.mov",             "contentThumbnail" : "url.jpg",             "contentRating" : "5",             "contentTitle" : "Guitar Lessons",             "username" : "Username",              "realname" : "Real name",             "contentTags" : [                 { "tag" : "Guitar"},                 { "tag" : "Intermediate"},                 { "tag" : "Chords"}             ],                   "contentAbout" : "Learn how to play guitar!",             "contentTime" : [                 { "" : "", "" : "", "" : "", "" : ""},                 { "" : "", "" : "", "" : "", "" : ""}             ],                       "series" :[                 { "seriesVideo" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "1", "seriesTitle" : "How to Play Guitar" },                 { "videoFile" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "2", "seriesTitle" : "How to Play Guitar" }             ]         }     ] } 

I've gotten my controller, factory, and html working when the JSON was hardcoded inside the factory. However, now that I've replaced the JSON with the $http.get code, it doesn't work. I've seen so many different examples of both $http and $resource but not sure where to go. I'm looking for the simplest solution. I'm just trying to pull data for ng-repeat and similar directives.

Factory:

theApp.factory('mainInfoFactory', function($http) {      var mainInfo = $http.get('content.json').success(function(response) {         return response.data;     });     var factory = {}; // define factory object     factory.getMainInfo = function() { // define method on factory object         return mainInfo; // returning data that was pulled in $http call     };     return factory; // returning factory to make it ready to be pulled by the controller }); 

Any and all help is appreciated. Thanks!

like image 825
jstacks Avatar asked Jun 05 '13 02:06

jstacks


People also ask

How do we pass data and get data using http in angular?

Use the HttpClient.get() method to fetch data from a server. The asynchronous method sends an HTTP request, and returns an Observable that emits the requested data when the response is received. The return type varies based on the observe and responseType values that you pass to the call.

Which object does the http GET () function return?

HttpClient. get() returns the body of the response as an untyped JSON object by default.

What does location Path Path do?

path([path]); This method is getter / setter. Return path of current URL when called without any parameter. Change path when called with parameter and return $location . Note: Path should always begin with forward slash (/), this method will add the forward slash if it is missing.

What is server communication in AngularJS using $HTTP?

The $http service is a core AngularJS service that facilitates communication with the remote HTTP servers via the browser's XMLHttpRequest object or via JSONP. For unit testing applications that use $http service, see $httpBackend mock.


2 Answers

I wanted to note that the fourth part of Accepted Answer is wrong .

theApp.factory('mainInfo', function($http) {   var obj = {content:null};  $http.get('content.json').success(function(data) {     // you can do some processing here     obj.content = data; });      return obj;     }); 

The above code as @Karl Zilles wrote will fail because obj will always be returned before it receives data (thus the value will always be null) and this is because we are making an Asynchronous call.

The details of similar questions are discussed in this post


In Angular, use $promise to deal with the fetched data when you want to make an asynchronous call.

The simplest version is

theApp.factory('mainInfo', function($http) {      return {         get:  function(){             $http.get('content.json'); // this will return a promise to controller         } });   // and in controller  mainInfo.get().then(function(response) {      $scope.foo = response.data.contentItem; }); 

The reason I don't use success and error is I just found out from the doc, these two methods are deprecated.

The $http legacy promise methods success and error have been deprecated. Use the standard then method instead.

like image 40
Qiang Avatar answered Oct 19 '22 04:10

Qiang


Okay, here's a list of things to look into:

1) If you're not running a webserver of any kind and just testing with file://index.html, then you're probably running into same-origin policy issues. See:

https://code.google.com/archive/p/browsersec/wikis/Part2.wiki#Same-origin_policy

Many browsers don't allow locally hosted files to access other locally hosted files. Firefox does allow it, but only if the file you're loading is contained in the same folder as the html file (or a subfolder).

2) The success function returned from $http.get() already splits up the result object for you:

$http({method: 'GET', url: '/someUrl'}).success(function(data, status, headers, config) { 

So it's redundant to call success with function(response) and return response.data.

3) The success function does not return the result of the function you pass it, so this does not do what you think it does:

var mainInfo = $http.get('content.json').success(function(response) {         return response.data;     }); 

This is closer to what you intended:

var mainInfo = null; $http.get('content.json').success(function(data) {     mainInfo = data; }); 

4) But what you really want to do is return a reference to an object with a property that will be populated when the data loads, so something like this:

theApp.factory('mainInfo', function($http) {       var obj = {content:null};      $http.get('content.json').success(function(data) {         // you can do some processing here         obj.content = data;     });          return obj;     }); 

mainInfo.content will start off null, and when the data loads, it will point at it.

Alternatively you can return the actual promise the $http.get returns and use that:

theApp.factory('mainInfo', function($http) {      return $http.get('content.json'); }); 

And then you can use the value asynchronously in calculations in a controller:

$scope.foo = "Hello World"; mainInfo.success(function(data) {      $scope.foo = "Hello "+data.contentItem[0].username; }); 
like image 192
Karen Zilles Avatar answered Oct 19 '22 04:10

Karen Zilles