I'm working on an Angular app that contains a list of (financial) Trades that a user can add to. This has been going well, and I'm trying to switch over from a static list provided by a service to trying to fetch the data from a local Node.js server. I'm using an observer to asynchronously fetch the list of trades.
I've been following along with Angular's HTTP tutorial and the associated plunker. However, even though I can see the data coming from the server, I'm having trouble using the .subscribe() method to get a useful set of data out of it.
Here's my service which connects to the node server:
@Injectable()
export class TradeService {
private url = '...'; // URL to web API
tradeArray: Trade[] = [];
constructor(private http: Http) { }
//-----------GETTERS---------------//
getTradeObservable(): Observable<Trade> {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
console.log("body:" + body);
console.log("Entire Body.trades: " + body.trades);
return body.trades;
}
getTrades(): any {
this.getTradeObservable()
.subscribe(
trade => this.tradeArray.push(trade));
return this.tradeArray;
}
And here are the relevant portions the node server itself:
var TRADES = { "trades": [
{"id": 0, "cust": "Ben", "hasSub": true,
"subcust": "Rigby", "type": "s", "security": "001", "ticket": "99"},
...
{"id": 9, "cust": "Uber Bank", "hasSub": true,
"subcust": "Lil Bank", "type": "p", "security": "456", "ticket": "56"}
]};
////////////Get Requests/////////////////
//this route returns all data in JSON format
app.get('/', function(req, res) {
res.send(JSON.stringify(TRADES));
});
And the expected output from getTrades:
[
{id: 0, cust: "Ben", hasSub: true,
subCust: "Rigby", type: "s", security: '001', ticket: '99'},
...
{id: 9, cust: "Uber Bank", hasSub: true,
subCust: "Lil' Bank", type: "p", security: '456', ticket: '56'},
];
And one of the places the service is injected into and called:
export class SubmittedComponent {
constructor(private tradeService: TradeService) { }
//initally show all trades
rows = this.tradeService.getTrades();
...
I can see in the browser console that 'entire body.trades' is a full list of the data I want, but it seems subscribe is not pushing them into tradeArray, which ends up undefined.
Thank you for your time.
So I suppose that you are calling getTrades() from one of your components. If this is the case, this is what will happen:
To avoid this, you could refactor you components so that they invoke the getTradeObservable()
method an subscribe to the returned Observable
.
UPDATE: Another option would be to refactor you service to use a Subject', and expose it to your components through an
Observable`.
UPDATE: Assuming that you have the following definition for Trade
export interface Trade{
id: number;
cust: string;
hasSub: boolean;
subCust: string;
type: string;s
security: string;
ticket: string;
}
You could try the following approach
class TestComponent {
data: Trade[];
// inject service in component
getData(){
this.service.getTradesObservable().subscribe(data => this.data = data);
}
}
And change the definition of getTradesObservable to :
getTradeObservable(): Observable<Trade[]> {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
}