我试图通过使用Angular2模块Http来检索本地json文件的内容。
我得到的错误是一个未定义的属性,但我认为它应该在Observable / Subscribe调用onComplete的prepareCredentials函数时初始化。
以下是错误,
class LaunchScene: SKScene {
override func didMoveToView(view: SKView) {
let background = SKSpriteNode(imageNamed: "Wall")
background.size = CGSize(width: 1600, height: 1200)
background.position = CGPoint(x: CGRectGetMidX(self.frame),
y: CGRectGetMidY(self.frame))
self.addChild(background)
self.view!.wantsLayer = true
let button = NSButton(frame: NSRect(x: self.frame.width/2,
y: self.frame.height/2, width: 50, height: 25))
self.view!.addSubview(button)
组件,
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)
和服务,
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);
}
}
提前感谢任何帮助或指示,因为这对我来说都是相对较新的。
答案 0 :(得分:2)
我想你的问题就在这里:
this.http.get('../app/data/credentials.json')
.map(this.handleResponse)
.subscribe(
this.setupCredentials, <==
this.handleError,
() => { this.prepareCredentials(); }
);
如果您直接传递方法引用,那么这是默认的JS / TS行为。您可以使用this.setupCredentials.bind(this)
之类的绑定或使用arrow function来保留this
:
this.http.get('../app/data/credentials.json')
.map(this.handleResponse)
.subscribe(
(data) => this.setupCredentials(data),
(res) => this.handleError(res),
() => { this.prepareCredentials(); }
);
希望它可以帮到你!