Reputation: 6155
I am busy writing a service to return data to a component in my angular app (ng4). The data is retrieved from a smart contract.
I seem to be getting the following error:
HomeComponent_Host.html:1 ERROR TypeError: this.smartContractService.getDrawId(...).subscribe is not a function
My component code:
this.smartContractService.getDrawId().subscribe(data => {
console.log('Result:: ', data);
});
And my service method:
getDrawId(): Observable<any> {
let gameObject;
return this.Game
.deployed()
.then(instance => {
gameObject = instance;
return gameObject.getDrawId.call();
})
.then(value => {
return value; //console.log(value) returns the data.
})
.catch(error => {
console.error('Error getting draw id; see log.');
console.log(error);
});
}
I am not sure how to get the data back from the service and to the calling component...
Upvotes: 0
Views: 407
Reputation: 84902
You seem to be trying to combine promises and observables. Promises and observables have a bit of similarity, since they're both intended to deal with asynchronous things. But while promises only ever deal with 1 eventual value, Observables deal with a stream of 0, 1, or many values.
Apparently, this.Game.deployed() is returning a promise, because you're calling .then
on it (which is the way you interact with promises). However, getDrawId claims to return an Observable<any>
, and you're calling .subscribe
; a function that only exists on observables, not promises.
So the path forward depends on what your intent is. Since this.game.deployed returns a promise, perhaps you want to use promises throughout, in which case you can do this:
getDrawId(): Promise<any> { //<--- type changed
let gameObject;
return this.Game
.deployed()
.then(instance => {
gameObject = instance;
return gameObject.getDrawId.call();
})
.then(value => {
return value; //console.log(value) returns the data.
})
.catch(error => {
console.error('Error getting draw id; see log.');
console.log(error);
});
}
// And use it with .then instead of .subscribe
this.smartContractService.getDrawId().then(data => {
console.log('Result:: ', data);
});
Alternatively, maybe you want getDrawId to return an observable, in which case you could either do a larger refactor in which you make this.Game.deployed() use observables so that you're using them throughout; or you could leave that as is and create an observable around the promise:
getDrawId(): Observable<any> {
let gameObject;
return Observable.fromPromise(this.Game
.deployed()
.then(instance => {
gameObject = instance;
return gameObject.getDrawId.call();
})
.then(value => {
return value; //console.log(value) returns the data.
})
.catch(error => {
console.error('Error getting draw id; see log.');
console.log(error);
});
);
}
Also, while I left in the <any>
s from your code, i'd recommend making a more specific type if you know it.
Upvotes: 2