AngularJS: factory $ http.get JSON फ़ाइल


84

मैं सिर्फ एक हार्डकोड JSON फ़ाइल के साथ स्थानीय रूप से विकसित होना चाह रहा हूं। मेरी JSON फ़ाइल निम्नानुसार है (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" }
            ]
        }
    ]
}

मैंने अपना कंट्रोलर, फैक्ट्री और html काम कर लिया है जब JSON फैक्ट्री के अंदर हार्डकोड किया गया था। हालाँकि, अब मैंने JSON को $ http.get कोड के साथ बदल दिया है, यह काम नहीं करता है। मैंने $ http और $ संसाधन दोनों के कई अलग-अलग उदाहरण देखे हैं, लेकिन निश्चित नहीं है कि कहाँ जाना है। मैं सबसे सरल उपाय ढूंढ रहा हूं। मैं सिर्फ एनजी-रिपीट और इसी तरह के निर्देशों के लिए डेटा खींचने की कोशिश कर रहा हूं।

फैक्टरी:

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

छोटी या बडी सब तरह की मदद सराहनीय है। धन्यवाद!


1
यह काम नहीं करता है? यह क्या करता है? क्या यह एक त्रुटि फेंकती है? जावास्क्रिप्ट कंसोल में कोई आउटपुट है?
जोश ली

कंसोल बस कहता है "संसाधन लोड करने में विफल" और फिर कंसोल है। Json फ़ाइल पथ। तो यह किसी कारण से इसे लोड नहीं कर रहा है। मेरी फैक्ट्री और JSON ठीक वैसी ही है जैसी आप ऊपर देखते हैं। जब मैं JSON को कारखाने में हार्डकोड करता हूं, तो यह काम करता है।
5’13

1
आप अपने बैकएंड के रूप में क्या उपयोग कर रहे हैं? NodeJs या एक साधारण अजगर आधारित सर्वर या कुछ और?
callmekatootie

मैं सिर्फ बैकएंड (रेल) को छोड़कर विकसित करने की कोशिश कर रहा हूं। तो JSON हार्डकोड के ऊपर डेटा के साथ सिर्फ एक .json फ़ाइल है। संभवतः बैकएंड क्या प्रस्तुत करेगा के समान।
jstacks

प्रतिक्रिया पर आपको ".डेटा" की आवश्यकता नहीं हो सकती है - परिवर्तन - "वापसी प्रतिक्रिया" के लिए, जब तक कि आपका लौटा हुआ JSON 'डेटा' ऑब्जेक्ट के अंदर बंडल न हो जाए।
भास्कर केम्पैया

जवाबों:


218

ठीक है, यहाँ देखने के लिए चीजों की एक सूची है:

1) यदि आप किसी भी प्रकार का वेबसर्वर नहीं चला रहे हैं और केवल फ़ाइल के साथ परीक्षण कर रहे हैं: //index.html, तो आप संभवतः समान-मूल नीति के मुद्दों में चल रहे हैं। देख:

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

कई ब्राउज़र स्थानीय रूप से होस्ट की गई फ़ाइलों को अन्य स्थानीय रूप से होस्ट की गई फ़ाइलों तक पहुँचने की अनुमति नहीं देते हैं। फ़ायरफ़ॉक्स इसे अनुमति देता है, लेकिन केवल अगर आप जिस फ़ाइल को लोड कर रहे हैं वह उसी फ़ोल्डर में HTML फ़ाइल (या सबफ़ोल्डर) के रूप में निहित है।

2) सफलता समारोह $ http.get () से लौटा है जो पहले से ही आपके लिए परिणाम ऑब्जेक्ट को विभाजित करता है:

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

तो यह फ़ंक्शन (प्रतिक्रिया) और वापसी response.data के साथ सफलता को कॉल करने के लिए अनावश्यक है।

3) सफलता समारोह आपके द्वारा पारित फ़ंक्शन के परिणाम को वापस नहीं करता है, इसलिए यह वह नहीं करता है जो आप सोचते हैं कि यह करता है:

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

यह आपके इच्छित उद्देश्य के करीब है:

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

4) लेकिन आप वास्तव में क्या करना चाहते हैं एक वस्तु के संदर्भ में एक संपत्ति के साथ वापसी होती है जो डेटा लोड होने पर पॉपुलेटेड हो जाएगी, इसलिए कुछ इस तरह से है:

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 अशक्त शुरू हो जाएगा, और जब डेटा लोड होता है, तो यह उस पर इंगित करेगा।

वैकल्पिक रूप से आप वास्तविक वादा $ http.get रिटर्न लौटा सकते हैं और उसका उपयोग कर सकते हैं:

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

और फिर आप एक नियंत्रक में गणना में अतुल्यकालिक रूप से मूल्य का उपयोग कर सकते हैं:

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

27
अरे यह एक ही कीमत के लिए एक प्रतिक्रिया और एक कोणीय $ http कोर्स है - अच्छा जवाब!
Mat

4
4) के तहत आपके स्पष्टीकरण में, $ http.get () हल होने से पहले 'रिटर्न ओबज' नहीं मिलेगा? सिर्फ इसलिए पूछ रहा हूं क्योंकि मुझे लगता है कि मेरे साथ ऐसा हो रहा है।
पाथ्सोफेन्सिग्न

3
हाँ यह होगा। लेकिन जब $ http.get () को हल किया जाता है, तो क्लोजर 'obj' का संदर्भ रखता है। यह सामग्री संपत्ति में भर जाएगा जिसे आप तब उपयोग कर सकते हैं।
करेन जिल्स

# 4 का उपयोग करके # 3 ओवर के दूसरे रूप का उपयोग करने में क्या समस्या है?
स्पेंसर

1
जंजीर कॉलबैक। असफल () को हटा दिया गया है। इसके बजाय .then (सफलता, त्रुटि) का उपयोग करें।
टिमोथी पेरेज़

21

मैं यह नोट करना चाहता था कि स्वीकृत उत्तर का चौथा भाग गलत है

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

@Karl Zilles के रूप में उपरोक्त कोड विफल हो objजाएगा क्योंकि डेटा प्राप्त करने से पहले इसे हमेशा वापस कर दिया जाएगा (इस प्रकार मूल्य हमेशा रहेगा null) और यह इसलिए है क्योंकि हम एक एसिंक्रोनस कॉल कर रहे हैं

इस पोस्ट में इसी तरह के सवालों के विवरण पर चर्चा की गई है


$promiseजब आप एक एसिंक्रोनस कॉल करना चाहते हैं , तो कोणीय डेटा से निपटने के लिए कोणीय में उपयोग करें।

सबसे सरल संस्करण है

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

कारण जो मैं उपयोग नहीं करता हूं successऔर errorक्या मुझे सिर्फ डॉक्टर से पता चला है , इन दो तरीकों को हटा दिया गया है।

$httpविरासत वादा तरीकों सफलता और त्रुटि पदावनत किया गया है। thenइसके बजाय मानक विधि का उपयोग करें ।


2
return $http.get('content.json');कारखाने में उपयोग करें , अन्यथा वापसी शून्य है।
फ्रांसेस्को

2
अरे, बस एक सिर। कारण यह काम करता है (यहाँ आपके उत्तर के विपरीत) यह है कि आप किसी वस्तु का संदर्भ लौटा रहे हैं। सफलता समारोह में उसी वस्तु का संदर्भ भी होता है। जब अजाक्स फ़ंक्शन अंत में वापस आ जाता है, तो यह मूल वस्तु में "सामग्री" संपत्ति को अद्यतन करता है जो वापस आ गया था। कोशिश करो। :-)
करेन ज़िल्स

1
पीएस .successअब पदावनत हो गया है। .thenइसके बजाय उपयोग करें । docs.angularjs.org/api/ng/service/$http
redfox05

4

इस जवाब ने मुझे बहुत मदद की और मुझे सही दिशा में इशारा किया लेकिन मेरे लिए क्या काम किया, और दूसरों को उम्मीद है, यह है:

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

6
क्या आपको सेवा के अंदर ऐसा कुछ नहीं करना चाहिए?
कटान २४

एक नियंत्रक में ऐसा कभी मत करो! खराब! आपके पास यह एक सेवा के रूप में लिखा होना चाहिए। हालाँकि जिस तरह से आपने json value कहा है वह गलत नहीं है, फिर भी आपको एक कंट्रोलर में वादे को पूरा न करने वाली सेवा वापस करनी चाहिए। एक पुन: प्रयोज्य दृष्टिकोण से और साथ ही यह भयानक है। उदाहरण के लिए, आप प्रदर्शन कर रहे हैं और $ http.get () हर बार जब आप किसी सेवा में कॉल का कैश्ड संस्करण बनाम कंट्रोलर लोड करते हैं।
डाउनपोर046

1

मुझे लगभग ये समस्या है। मुझे Visual Studio 2013 से AngularJs एप्लिकेशन को डीबग करने की आवश्यकता है।

डिफ़ॉल्ट रूप से IIS एक्सप्रेस द्वारा स्थानीय फ़ाइलों (जैसे json) तक पहुँच प्रतिबंधित है।

लेकिन, पहले: JSON में जावास्क्रिप्ट सिंटैक्स है।

दूसरा: जावास्क्रिप्ट फ़ाइलों की अनुमति है।

इसलिए:

  1. जेएसएन का नाम बदलकर जेएस ( data.json->data.js) कर दिया।

  2. सही लोड कमांड ($http.get('App/data.js').success(function (data) {...

  3. पृष्ठ के लिए स्क्रिप्ट data.js लोड करें ( <script src="App/data.js"></script>)

अगला लोड किया गया डेटा सामान्य तरीके से उपयोग करें। यह सिर्फ वर्कअराउंड है, बिल्कुल।


1

++ यह मेरे लिए काम किया। लाइब्रेरी के vanilla javascirptसाथ परीक्षण करते समय डी-क्लटरिंग जैसे उपयोग के मामलों के लिए यह अच्छा है 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>

यह आपकी javascriptफ़ाइल है जिसमें 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"
};

अंत में, अपने कोड में कहीं भी JSON डेटा के साथ काम करें

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

नोट: - यह परीक्षण के लिए बहुत अच्छा है और यहां तक ​​कि karma.conf.jsनीचे दिए गए परीक्षणों के अनुसार इन फ़ाइलों को चलाने के लिए स्वीकार करता है। इसके अलावा, मैं इसे केवल डी-क्लटरिंग डेटा और testing/developmentपर्यावरण के लिए सलाह देता हूं ।

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

उम्मीद है की यह मदद करेगा।

++ इस उत्तर के शीर्ष पर निर्मित https://stackoverflow.com/a/24378510/4742733

अपडेट करें

मेरे लिए काम करने का एक आसान तरीका बस functionजो भी लौट रहा कोड के तल पर शामिल है 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"
   }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.