2016-05-26 10 views
5

Ich versuche, den Inhalt einer lokalen JSON-Datei durch die Verwendung des Angular2-Moduls Http abzurufen.Eigenschaft undefined Angular2 und TypeScript

Der Fehler, den ich bekomme, ist von einer undefinierten Eigenschaft, aber ich denke, es sollte initialisiert worden sein, wenn die prepareCredentials -Funktion onComplete von der Observable/Subscribe aufgerufen wird.

folgt hier die Fehler,

TypeError: Cannot read property 'clientId' of undefined 
    at SpotifyComponent.prepareCredentials (spotify.component.ts:58) 
    at SafeSubscriber.eval [as _complete] (spotify.component.ts:38) 
    at SafeSubscriber.__tryOrUnsub (Subscriber.ts:240) 
    at SafeSubscriber.complete (Subscriber.ts:226) 
    at Subscriber._complete (Subscriber.ts:142) 
    at Subscriber.complete (Subscriber.ts:120) 
    at MapSubscriber.Subscriber._complete (Subscriber.ts:142) 
    at MapSubscriber.Subscriber.complete (Subscriber.ts:120) 
    at XMLHttpRequest.onLoad (xhr_backend.ts:67) 
    at ZoneDelegate.invokeTask (zone.js:356) 

Komponente,

import { Component, OnInit } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 

import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 

import { SpotifyService } from './spotify.service'; 

@Component({ 
    moduleId: module.id, 
    selector: 'app-spotify', 
    templateUrl: 'spotify.component.html', 
    styleUrls: ['spotify.component.css'], 
    providers: [SpotifyService] 
}) 

export class SpotifyComponent implements OnInit { 
    private credentialsData: { 
    clientId: string, 
    clientSecret: string 
    }; 

    constructor(
    private http: Http, 
    private spotifyService: SpotifyService 
) { } 

    ngOnInit() { 
    if (this.spotifyService) { 
     this.http.get('../app/data/credentials.json') 
     .map(this.handleResponse) 
     .subscribe(
      this.setupCredentials, 
      this.handleError, 
     () => { this.prepareCredentials(); } 
     ); 
    } 
    } 

    private setupCredentials(subData) { 
    console.log('Setting up credentials...'); 
    this.credentialsData = { 
     clientId: <string>subData.clientId, 
     clientSecret: <string>subData.clientSecret 
    }; 
    console.log('credentials: ' + 
     JSON.stringify(this.credentialsData)); 
    console.log('credentials clientId: ' + this.credentialsData.clientId); 
    console.log('credentials clientSecret: ' + this.credentialsData.clientSecret); 
    } 

    private prepareCredentials() { 
    console.log('Preparing credentials...'); 
    this.spotifyService.prepare(
     this.credentialsData.clientId, 
     this.credentialsData.clientSecret, 
     '', 'http://localhost:4200/spotify'); 

    } 

    private handleResponse(res: Response) { 
    console.log(JSON.stringify(res.json())); 
    return res.json().spotify; 
    } 

    private handleError(error: any) { 
    let errMsg = (error.message) ? error.message : 
     error.status ? `${error.status} - ${error.statusText}` : 'Server  error'; 
    console.error(errMsg); // log to console instead 
    return Observable.throw(errMsg); 
    } 

} 

und den Service,

import { Injectable } from '@angular/core'; 

@Injectable() 
export class SpotifyService { 
    private clientId: string; 
    private clientSecret: string; 
    private scopes: string; 
    private callbackUrl: string; 

    constructor() { } 

    wakeUpTest(): string { 
    console.log('SpotifyService is awake and initiated.'); 
    return 'SpotifyService is awake and initiated.'; 
    } 

    prepare(clientId: string, 
    clientSecret: string, 
    scopes: string, 
    callbackUrl: string): void { 
     console.log(clientId); 
    } 

    getAuthCode(): void { 
    let authUrl: string = 'https://accounts.spotify.com/authorize' + 
     '?response_type=code' + 
     '&client_id=' + this.clientId + 
     '&scope=' + encodeURIComponent(this.scopes) + 
     '&redirect_uri=' + encodeURIComponent(this.callbackUrl); 
    } 

} 

Vielen Dank im Voraus für jede Hilfe oder Zeiger als all dies ist relativ neu für mich.

Antwort

2

Ich nehme an, dass Ihr Problem hier befindet:

this.http.get('../app/data/credentials.json') 
    .map(this.handleResponse) 
    .subscribe(
    this.setupCredentials, <== 
    this.handleError, 
    () => { this.prepareCredentials(); } 
); 

Das ist Standard-JS/TS Verhalten, wenn Sie direkt eine Methode Referenz übergeben. Sie können entweder binden wie this.setupCredentials.bind(this) verwenden oder verwenden arrow functionthis zu behalten:

this.http.get('../app/data/credentials.json') 
    .map(this.handleResponse) 
    .subscribe(
     (data) => this.setupCredentials(data), 
     (res) => this.handleError(res), 
    () => { this.prepareCredentials(); } 
    ); 

Hoffe, es hilft Ihnen!

+0

Dies geschieht implizit, würde ich annehmen, wie ich alle Ausdrucke in SetupCredentials gretet? Es ist auch die gleiche Praxis, die in der Winkeldokumentation durchgeführt wird, wobei lediglich die Funktion für einen impliziten Datendurchlauf übergeben wird. –

+0

Probieren Sie 'this' vor 'console.log ('Anmeldedaten einrichten ...') aus;' – yurzui

+0

Das Ausdrucken dieses 'gab mir den Ausdruck eines 'SafeSubscriber'-Objekts, [so] (http: // pastebin. com/M4GDSZv1). –

Verwandte Themen