AngularJS: archivo JSON factory $ http.get

Estoy buscando desarrollar localmente con solo un archivo JSON codificado. Mi archivo JSON es el siguiente (válido cuando se coloca en el validador JSON):

{ "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" } ] } ] } 

He conseguido que mi controlador, fábrica y html funcionen cuando el JSON estaba codificado dentro de la fábrica. Sin embargo, ahora que he reemplazado el JSON con el código $ http.get, no funciona. He visto tantos ejemplos diferentes de recursos $ http y $ pero no estoy seguro de dónde ir. Estoy buscando la solución más simple. Solo bash extraer datos para ng-repeat y directivas similares.

Fábrica:

 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 }); 

Cualquier y toda ayuda es apreciada. ¡Gracias!

De acuerdo, aquí hay una lista de cosas a considerar:

1) Si no está ejecutando un servidor web de ningún tipo y solo está probando con file: //index.html, entonces probablemente se encuentre con problemas de política del mismo origen. Ver:

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

Muchos navegadores no permiten que los archivos alojados localmente accedan a otros archivos alojados localmente. Firefox lo permite, pero solo si el archivo que estás cargando está contenido en la misma carpeta que el archivo html (o una subcarpeta).

2) La función de éxito devuelta desde $ http.get () ya divide el objeto de resultado por usted:

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

Por lo tanto, es redundante llamar éxito a la función (respuesta) y devolver response.data.

3) La función de éxito no devuelve el resultado de la función que lo pasa, por lo que no hace lo que cree que hace:

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

Esto está más cerca de lo que pretendías:

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

4) Pero lo que realmente desea hacer es devolver una referencia a un objeto con una propiedad que se completará cuando se carguen los datos, por lo que algo como esto:

 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 comenzará nulo, y cuando se carguen los datos, apuntará a él.

Alternativamente, puede devolver la promesa real que devuelve $ http.get y usar eso:

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

Y luego puede usar el valor de forma asincrónica en los cálculos en un controlador:

 $scope.foo = "Hello World"; mainInfo.success(function(data) { $scope.foo = "Hello "+data.contentItem[0].username; }); 

Quería señalar que la cuarta parte de la Respuesta aceptada es incorrecta .

 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; }); 

El código anterior como @Karl Zilles escribió fallará porque obj siempre se devolverá antes de que reciba datos (por lo tanto, el valor siempre será null ) y esto se debe a que estamos realizando una llamada asincrónica.

Los detalles de preguntas similares se discuten en esta publicación


En Angular, use $promise para tratar con los datos obtenidos cuando desee realizar una llamada asincrónica.

La versión más simple es

 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; }); 

La razón por la que no utilizo el success y el error es que acabo de descubrirlo del documento , estos dos métodos están en desuso.

El éxito y el error de los métodos de promesa heredados de $http se han desaprobado. Use el método estándar then lugar.

Esta respuesta me ayudó mucho y me dirigió en la dirección correcta, pero lo que funcionó para mí, y espero que otros, es:

 menuApp.controller("dynamicMenuController", function($scope, $http) { $scope.appetizers= []; $http.get('config/menu.json').success(function(data) { console.log("success!"); $scope.appetizers = data.appetizers; console.log(data.appetizers); }); }); 

Tengo aproximadamente estos problemas Necesito depurar la aplicación AngularJs de Visual Studio 2013.

De forma predeterminada, IIS Express tiene acceso restringido a archivos locales (como json).

Pero, primero: JSON tiene syntax de JavaScript.

Segundo: los archivos javascript están permitidos.

Asi que:

  1. cambie el nombre de JSON a JS ( data.json->data.js ).

  2. comando de carga correcta ( $http.get('App/data.js').success(function (data) {...

  3. cargar el script data.js a la página ( )

A continuación, use los datos cargados de la manera habitual. Es solo una solución, por supuesto.

++ Esto funcionó para mí. Es un vanilla javascirpt y es bueno para casos de uso como ngMocks cuando se prueba con la biblioteca ngMocks :

     

Este es su archivo javascript que contiene los datos JSON

 // json-data/JSONFindByIdResults.js var JSONFindByIdResults = { "Title": "Star Wars", "Year": "1983", "Rated": "N/A", "Released": "01 May 1983", "Runtime": "N/A", "Genre": "Action, Adventure, Sci-Fi", "Director": "N/A", "Writer": "N/A", "Actors": "Harrison Ford, Alec Guinness, Mark Hamill, James Earl Jones", "Plot": "N/A", "Language": "English", "Country": "USA", "Awards": "N/A", "Poster": "N/A", "Metascore": "N/A", "imdbRating": "7.9", "imdbVotes": "342", "imdbID": "tt0251413", "Type": "game", "Response": "True" }; 

Finalmente, trabaje con los datos JSON en cualquier parte de su código

 // working with JSON data in code var findByIdResults = window.JSONFindByIdResults; 

Nota: – Esto es excelente para probar e incluso karma.conf.js acepta estos archivos para ejecutar pruebas como se ve a continuación. Además, lo recomiendo solo para desordenar datos y testing/development entorno de testing/development .

 // extract from karma.conf.js files: [ 'json-data/JSONSearchResultHardcodedData.js', 'json-data/JSONFindByIdResults.js' ... ] 

Espero que esto ayude.

++ Construido sobre esta respuesta https://stackoverflow.com/a/24378510/4742733

ACTUALIZAR

Una forma más sencilla que funcionó para mí es simplemente incluir una function en la parte inferior del código que devuelva lo que JSON .

 // within test code let movies = getMovieSearchJSON(); ..... ... ... .... // way down below in the code function getMovieSearchJSON() { return { "Title": "Bri Squared", "Year": "2011", "Rated": "N/A", "Released": "N/A", "Runtime": "N/A", "Genre": "Comedy", "Director": "Joy Gohring", "Writer": "Briana Lane", "Actors": "Brianne Davis, Briana Lane, Jorge Garcia, Gabriel Tigerman", "Plot": "N/A", "Language": "English", "Country": "USA", "Awards": "N/A", "Poster": "http://sofes.miximages.com/json/MV5BMjEzNDUxMDI4OV5BMl5BanBnXkFtZTcwMjE2MzczNQ@@._V1_SX300.jpg", "Metascore": "N/A", "imdbRating": "8.2", "imdbVotes": "5", "imdbID": "tt1937109", "Type": "movie", "Response": "True" } }