2017-02-22 22 views
1

Я строю одностраничное приложение для небольшого проекта. Я пытался сохранить данные из вызова API в базу данных фильмов в объекте. Если я console.log объекта, я могу увидеть все его свойства и значения. Если я console.log object.property, он возвращает 'undefined'. Это код:Свойства объекта не определены, сам объект показывает все данные, но

(() => { 
"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']), он возвращает «Undefined» в консоли. Кто-нибудь знает, как это исправить?

+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, зарегистрируйте его оттуда. Или, если вы построили allData позже в cleanData, тогда вызовите журналы после функции cleanData.

Чтобы ответить на ваш вопрос, ни один из ваших журналов не должен работать, так как это асинхронный вызов. Вы получаете allData в связи с тем, как console.log работает со ссылками, которые обновляются позже, используйте console.log(JSON.stringify(allData)), чтобы получить фактический моментальный снимок объекта

+0

Большое спасибо за ваш ответ! :) –