web-dev-qa-db-fra.com

AngularJS: fichier JSON d'usine $ http.get

Je cherche à développer localement avec juste un fichier JSON codé en dur. Mon fichier JSON est le suivant (valide lorsqu'il est placé dans le validateur 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" }
            ]
        }
    ]
}

J'ai utilisé mon contrôleur, mon usine et mon code HTML lorsque le code JSON était codé en dur à l'intérieur de l'usine. Cependant, maintenant que j'ai remplacé le JSON par le code $ http.get, cela ne fonctionne pas. J'ai vu tellement d'exemples de ressources $ http et $ mais je ne sais pas trop où aller. Je cherche la solution la plus simple. J'essaie simplement d'extraire des données pour les directives ng-repeat et similaires.

Usine:

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

Toute aide est appréciée. Merci!

84
jstacks

Ok, voici une liste de choses à examiner:

1) Si vous n'exécutez aucun serveur Web et que vous ne faites que tester avec file: //index.html, vous êtes probablement confronté à des problèmes de stratégie de même origine. Voir:

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

De nombreux navigateurs n'autorisent pas les fichiers hébergés localement à accéder à d'autres fichiers hébergés localement. Firefox le permet, mais uniquement si le fichier que vous chargez est contenu dans le même dossier que le fichier HTML (ou un sous-dossier).

2) La fonction success renvoyée par $ http.get () divise déjà l’objet résultat pour vous:

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

Il est donc redondant d'appeler le succès avec function (réponse) et de renvoyer response.data.

3) La fonction de réussite ne renvoie pas le résultat de la fonction que vous lui transmettez. Elle ne fait donc pas ce que vous pensez qu'elle fait:

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

Ceci est plus proche de ce que vous vouliez:

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

4) Mais ce que vous voulez vraiment faire, c'est renvoyer une référence à un objet avec une propriété qui sera renseignée lors du chargement des données. Par exemple, procédez comme suit:

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 démarrera null et, lorsque les données seront chargées, il le pointera.

Sinon, vous pouvez retourner la promesse que $ http.get renvoie et utiliser:

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

Et vous pouvez ensuite utiliser la valeur de manière asynchrone dans les calculs d'un contrôleur:

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

Je voulais noter que la quatrième partie de la réponse acceptée est fausse .

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

Le code ci-dessus, écrit par @Karl Zilles, échouera car obj sera toujours renvoyé avant de recevoir des données (la valeur sera donc toujours null) et c'est parce que nous faisons un Appel asynchrone.

Les détails de questions similaires sont discutés dans ce post


Dans Angular, utilisez $promise pour traiter les données extraites lorsque vous souhaitez effectuer un appel asynchrone.

La version la plus simple est

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 raison pour laquelle je n'utilise pas success et error est que je viens de le découvrir grâce à la doc , ces deux méthodes sont obsolètes.

Le succès et l'erreur des méthodes de promesse héritées $http sont désormais obsolètes. Utilisez plutôt la méthode standard then.

21
Qiang

cette réponse m'a beaucoup aidé et m'a orientée dans la bonne direction, mais ce qui a fonctionné pour moi et, espérons-le, pour les autres, c'est:

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

++ Cela a fonctionné pour moi. C'est Vanilla javascirpt et convient aux cas d'utilisation tels que le désencombrement lors du test avec la bibliothèque ngMocks:

<!-- specRunner.html - keep this at the top of your <script> asset loading so that it is available readily -->
<!--  Frienly tip - have all JSON files in a json-data folder for keeping things organized-->
<script src="json-data/findByIdResults.js" charset="utf-8"></script>
<script src="json-data/movieResults.js" charset="utf-8"></script>

Ceci est votre fichier javascript qui contient les données 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"
};

Enfin, travaillez avec les données JSON n'importe où dans votre code.

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

Remarque: - C'est excellent pour les tests et même karma.conf.js accepte ces fichiers pour l'exécution des tests, comme indiqué ci-dessous. De plus, je recommande ceci uniquement pour désencombrer les données et l'environnement testing/development.

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

J'espère que cela t'aides.

++ construit sur cette réponse https://stackoverflow.com/a/24378510/47427

UPDATE

Un moyen plus simple qui fonctionne pour moi est d’inclure une function au bas du code renvoyant tout ce 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://ia.media-imdb.com/images/M/MV5BMjEzNDUxMDI4OV5BMl5BanBnXkFtZTcwMjE2MzczNQ@@._V1_SX300.jpg",
         "Metascore": "N/A",
         "imdbRating": "8.2",
         "imdbVotes": "5",
         "imdbID": "tt1937109",
         "Type": "movie",
         "Response": "True"
   }
}
1
Akash

J'ai à peu près ces problèmes. J'ai besoin de l'application de débogage AngularJs de Visual Studio 2013.

Par défaut IIS Express, l'accès restreint aux fichiers locaux (comme JSON).

Mais d'abord: JSON a la syntaxe JavaScript.

Deuxièmement: les fichiers javascript sont autorisés.

Alors:

  1. renommez JSON en JS (data.json->data.js).

  2. commande de chargement correcte ($http.get('App/data.js').success(function (data) {...

  3. charge le script data.js vers la page (<script src="App/data.js"></script>)

Ensuite, utilisez les données chargées de manière habituelle. C'est juste une solution de contournement, bien sûr.

1
Alex Sam