2017-02-22 40 views
1

我正在爲次要項目構建單頁應用程序。我一直在嘗試將API調用的數據保存到對象中的電影數據庫中。如果我console.log對象,我可以看到它的所有屬性和值。如果我console.log object.property,它返回'未定義'。這是代碼:對象屬性未定義,對象本身顯示所有數據雖然

(() => { 
"use strict" 

    /* Saving sections to variables 
    --------------------------------------------------------------*/ 
    const movieList = document.getElementsByClassName('movie_list')[0]; 
    const movieSingle = document.getElementsByClassName('movie_single')[0]; 

    /* All standard filters for displaying movies 
    --------------------------------------------------------------*/ 
    const allFilters = { 
    trending: 'movie/popular', 
    toplist: 'movie/top_rated', 
    latest: 'movie/now_playing', 
    upcoming: 'movie/upcoming' 
    }; 

    const allData = {}; 

    /* Initialize app - Get al standard data and save it in object 
    --------------------------------------------------------------*/ 
    const app = { 
    init() { 
     getData(allFilters.trending, 'popular'); 
     getData(allFilters.toplist, 'toplist'); 
     getData(allFilters.latest, 'latest'); 
     getData(allFilters.upcoming, 'upcoming'); 

     this.startPage(); 
    }, 
    startPage() { 
     window.location.hash = "trending"; 
    } 
    } 

    /* Function for getting data from the API 
    --------------------------------------------------------------*/ 
    const getData = (filter, key) => { 
    const request = new XMLHttpRequest(); 
    const apiKey = '?api_key=xxx'; 
    const getUrl = `https://api.themoviedb.org/3/${filter}${apiKey}`; 

    request.open('GET', getUrl, true); 
    request.onload =() => { 
     if (request.status >= 200 && request.status < 400) { 
     let data = JSON.parse(request.responseText); 
     data.filter = key; 
     cleanData.init(data); 
     } else { 
     window.location.hash = 'random'; 
     } 
    }; 
    request.onerror =() => { 
     console.error('Error'); 
    }; 
    request.send(); 
    }; 

    /* Check if the data is list or single, and clean up 
    --------------------------------------------------------------*/ 
    const cleanData = { 
    init(originalData) { 
     if (!originalData.results) { 
     this.single(originalData); 
     } else { 
     allData[originalData.filter] = originalData; 
     } 
    }, 

    list(data) { 
     data.results.map(function(el) { 
     el.backdrop_path = `https://image.tmdb.org/t/p/w500/${el.backdrop_path}`; 
     }); 
     let attributes = { 
     movie_image: { 
      src: function() { 
      return this.backdrop_path; 
      }, 
      alt: function() { 
      return this.title; 
      } 
     }, 
     title_url: { 
      href: function() { 
      return `#movie/${this.id}/${this.title}`; 
      } 
     } 
     } 
     showList(data.results, attributes); 
    }, 

    single(data) { 
     data.poster_path = `https://image.tmdb.org/t/p/w500/${data.poster_path}`; 
     data.budget = formatCurrency(data.budget); 
     data.revenue = formatCurrency(data.revenue); 
     data.runtime = `${(data.runtime/60).toFixed(1)} uur`; 
     data.imdb_id = `http://www.imdb.com/title/${data.imdb_id}`; 
     let attributes = { 
     movie_image: { 
      src: function() { 
      return this.poster_path; 
      }, 
      alt: function() { 
      return this.title; 
      } 
     }, 
     imdb_url: { 
      href: function() { 
      return this.imdb_id 
      } 
     }, 
     similar_url: { 
      href: function() { 
      return `#movie/${this.id}/${this.title}/similar` 
      } 
     } 
     }; 
     showSingle(data, attributes); 
    } 
    }; 

    const showList = (cleanedData, attributes) => { 
    movieList.classList.remove('hidden'); 
    movieSingle.classList.add('hidden'); 
    Transparency.render(movieList, cleanedData, attributes); 
    }; 

    const showSingle = (cleanedData, attributes) => { 
    movieSingle.classList.remove('hidden'); 
    movieList.classList.add('hidden'); 
    Transparency.render(movieSingle, cleanedData, attributes); 
    } 

const formatCurrency = amount => { 
    amount = amount.toFixed(0).replace(/./g, function(c, i, a) { 
     return i && c !== "." && ((a.length - i) % 3 === 0) ? '.' + c : c; 
    }); 
    return `€${amount},-`; 
    }; 

    app.init(); 

console.log(allData); // Returns object with 4 properties: trending, toplist, latest & upcoming. Each property is filled with 20 results (movies with data) from the API. 

console.log(allData.trending) // Returns 'undefined' (each property I've tried). 

console.log(allData['trending']) // Returns 'undefined' 

Object.keys(allData); // Returns an empty Array [] 

})(); 

當我使用console.log(allData)我看到4個屬性,無不洋溢着來自API的結果。但是,當我做console.log(allData.trending)console.log(allData['trending'])它在控制檯中返回'未定義'。有沒有人有一個想法如何解決這個問題?

+0

是什麼'Object.keys(ALLDATA)'的輸出的實際快照? –

+0

@AmreshVenugopal它返回一個空數組 –

+2

看起來像屬性不是對象。我的意思是,你在控制檯上看到的屬性來自原型。 –

回答

1

當您致電app.init()時,它會觸發init併發送api調用以獲取數據。

獲取數據的調用是異步的,這意味着它不會等待響應繼續執行。所以它繼續並執行下一行代碼,它們是您的console.logs。此時API調用沒有對數據做出響應,因此當您嘗試訪問data.property時,它會失敗,因爲數據尚未處理。

當您執行log(data)時,它會創建一個數據引用的日誌,當引用稍後填充值時,該日誌將在日誌中更新。要在該實例中獲得data的值,並在稍後阻止更新,請嘗試log(JSON.stringify(data))。當你這樣做時,你會得到一個一致的結果,你的日誌沒有任何工作,這是實際的行爲。

爲了讓您的日誌工作,請查看A(同步)JAX請求的成功/加載回調,並從那裏記錄日誌。或者如果您在cleanData之後構建allData,則在cleanData函數之後調用日誌。

所以要回答你的問題,你的任何日誌都不應該工作,因爲它是一個異步調用。你得到應有記錄到console.log與稍後更新引用的工作方式的allData,使用console.log(JSON.stringify(allData))獲得對象

+0

非常感謝您的回答! :) –