2017-02-22 4 views
1

Ich baue eine Single-Page-Anwendung für ein Nebenprojekt. Ich habe versucht, Daten von API-Aufrufen in die Movie-Datenbank in einem Objekt zu speichern. Wenn ich das Objekt console.log anmelde, kann ich alle seine Eigenschaften und Werte sehen. Wenn ich die Eigenschaft object.property console.log anschließe, wird 'undefined' zurückgegeben. Dies ist der Code:Objekteigenschaften sind undefiniert, das Objekt selbst zeigt alle Daten

(() => { 
"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 [] 

})(); 

Wenn ich console.log(allData) verwende ich 4 Objekte zu sehen, die alle mit den Ergebnissen aus der API gefüllt. Aber wenn ich console.log(allData.trending) oder console.log(allData['trending']) mache, gibt es 'Undefined' in der Konsole zurück. Hat jemand eine Idee wie man das beheben kann?

+0

zu bekommen, was ist die Ausgabe von 'Object.keys (allData)'? –

+0

@AmreshVenugopal es gibt ein leeres Array –

+2

Es scheint, als ob die Eigenschaften nicht von dem Objekt sind. Ich meine, die Eigenschaften, die Sie auf der Konsole sehen, stammen vom Prototyp. –

Antwort

1

Wenn Sie app.init() aufrufen, wird die init ausgelöst und der/die API-Aufruf (e) gesendet, um Daten abzurufen.

Der Aufruf zum Abrufen von Daten ist asynchron, was bedeutet, dass nicht auf die Ausführung der Antwort gewartet wird. So geht es weiter und führt die nächsten Codezeilen aus, die Ihre console.logs sind. Zu diesem Zeitpunkt haben die API-Aufrufe nicht mit den Daten geantwortet. Wenn Sie versuchen, auf data.property zuzugreifen, schlägt das fehl, da die Daten noch nicht vorliegen.

Wenn Sie log(data) tun, erstellt es ein Protokoll der Referenz auf Daten, die im Protokoll aktualisiert wird, wenn die Referenz später mit einem Wert gefüllt wird. Um den Wert data in dieser Instanz zu erhalten und eine spätere Aktualisierung zu verhindern, können Sie versuchen, log(JSON.stringify(data)). Wenn Sie dies tun, erhalten Sie ein konsistentes Ergebnis, keines Ihrer Protokolle funktioniert, was das tatsächliche Verhalten ist.

Um Ihre Protokolle arbeiten zu lassen, schauen Sie in den Erfolgs-/Lade-Callback Ihrer A (synchronen) JAX-Anfrage, loggen Sie sich von dort ein. Oder wenn Sie allData später in cleanData konstruiert haben, dann rufen Sie die Protokolle nach cleanData Funktion.

Um Ihre Frage zu beantworten, sollte keines Ihrer Protokolle funktionieren, da es sich um einen asynchronen Anruf handelt. Sie erhalten die allData protokolliert aufgrund der Art und Weise console.log arbeitet mit Referenzen, die später aktualisiert werden, verwenden Sie , um den tatsächlichen Snapshot von Objekt

+0

Vielen Dank für Ihre Antwort! :) –

Verwandte Themen