The potential 'duplicate' questions do not answer my question - I potentially think my use of Observables is different than the examples and as I point out, I attempted using share() unsuccessfully.
I have a service which looks like that:
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Card } from '../../card';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class CardService {
private privateUrl = 'http://localhost:3335/cardname/';
constructor (private http: Http) {}
public getDetailedInfo(card): Observable<Card> {
return this.http.get(`${this.privateUrl}${card.name}`)
.map(this.extractData);
}
private extractData(res: Response) {
let body = res.json();
return new Card(body.data.name, body.data.card_type, body.data.text);
}
}
And a component that uses it that looks like :
import { Component, OnInit } from '@angular/core';
import { Card } from '../../card';
import { CardService } from '../../services/card/card.service';
import { CARDNAMES } from '../../cards';
@Component({
selector: 'main',
styles: [require('./main.component.scss').toString()],
template: require('./main.component.html'),
providers: [CardService]
})
export class MainComponent implements OnInit {
mode = 'Observable';
title = 'YuGiOh Deck Browser';
cardnames = CARDNAMES;
card: Card;
selectedCard: Card;
dataStore: Array<any> = [];
constructor(private cardService: CardService) { }
ngOnInit() {
for (let prop in this.cardnames) {
this.getDetailedInfo(this.cardnames[prop]);
}
}
onSelect(card: Card): void {
this.getDetailedInfo(card);
}
getDetailedInfo(card) {
this.cardService.getDetailedInfo(card)
.subscribe((card: Card) => {
this.card = this.selectedCard = card;
this.dataStore.push(card);
});
}
}
My template is:
<div *ngIf="card">
<h2>{{card.name}}</h2>
<div class="card-type">{{card?.card_type}}</div>
<div class="card-description">{{card?.text}}</div>
</div>
and my Card looks like that:
export class Card {
response:string;
constructor(
public name: string,
public card_type: string,
public text: string
) { }
}
I tried using share()
, cache()
, publishReplay(1).refCount()
after reading this and that but nothing seems stop that HTTP Get request to be called when the click handler is called.
Am I misunderstanding what these methods actually do?
I also made an attempt, following this first answer in this question to save my data in an array of objects in memory (code sample following) which partially works, but fails when I click and trigger the onSelect event.
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Card } from '../../card';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class CardService {
private dataStore: Array<any> = [];
private observable: Observable<Card>;
private privateUrl = 'http://localhost:3335/cardname/';
constructor (private http: Http) {}
public getDetailedInfo(card): Observable<any> {
if (this.dataStore.length > 0) {
this.dataStore.forEach((value, index) => {
return new Card(
this.dataStore[index].data.name,
this.dataStore[index].data.card_type,
this.dataStore[index].data.text
)
});
} else if (this.observable) {
return this.observable;
} else {
return this.http.get(`${this.privateUrl}${card.name}`)
.map(
(res) => {
let body = res.json();
this.dataStore.push(body);
return new Card(body.data.name, body.data.card_type, body.data.text);
}
);
}
}
}
VM99537:93 EXCEPTION: Error in ./MainComponent class MainComponent - inline template:4:8
2016-09-11 21:04:03.241 zone.js?c625:269 Uncaught EXCEPTION: Error in ./MainComponent class MainComponent - inline template:4:8
ORIGINAL EXCEPTION: TypeError: Cannot read property 'subscribe' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property 'subscribe' of undefined
at MainComponent.getDetailedInfo (eval at <anonymous> (http://localhost:5000/bundle.js:965:2), <anonymous>:32:13)
at MainComponent.onSelect (eval at <anonymous> (http://localhost:5000/bundle.js:965:2), <anonymous>:27:14)
at DebugAppView._View_MainComponent1._handle_click_0_0 (MainComponent.ngfactory.js:172:35)
at eval (eval at <anonymous> (http://localhost:5000/common.js:1731:2), <anonymous>:381:24)
at eval (eval at <anonymous> (http://localhost:5000/common.js:2322:2), <anonymous>:255:36)
at eval (eval at <anonymous> (http://localhost:5000/common.js:2364:2), <anonymous>:27:111)
at ZoneDelegate.invoke (eval at <anonymous> (http://localhost:5000/vendor.js:472:2), <anonymous>:332:29)
at Object.onInvoke (eval at <anonymous> (http://localhost:5000/common.js:1551:2), <anonymous>:53:41)
at ZoneDelegate.invoke (eval at <anonymous> (http://localhost:5000/vendor.js:472:2), <anonymous>:331:35)
at Zone.runGuarded (eval at <anonymous> (http://localhost:5000/vendor.js:472:2), <anonymous>:239:48)