1

I'm writing an Angular app that gets a selection of stores from a service, as an Observable.

When the user clicks a marker on the map, I want to get the index of the store in the array that lives inside the Observable.

stores: Observable<Store[]>;

ngOnInit() {
    this.stores = http.get<Store[]>('URL');
}

onMarkerClick(event) {
   const geopoint = event.geopoint;
   //How can I get the index where store.geopoint === event.geopoint?
}
1
  • If this is a bad question, please let me know why instead of just downvoting. Commented Apr 29, 2018 at 22:07

2 Answers 2

2

For filtering the stores from the array you do:

this.storesCollection.filter(store => store.geopoint === event.geopoint); // -1 if not found

And for transforming the Observable to an Array use map:

this.stores$.map((stores: Stores[]) => this.storesCollection = stores)

You don't need to do subscribe() because http returns a hot observable, always firing regardless of there being a subscriber or not

Sign up to request clarification or add additional context in comments.

1 Comment

@Mark van Straten Ah yes, I added the part about mapping to a value. Next time you are welcome to comment on an incomplete answer without downvoting
1

If you want to lazily get your store[] from your backend you will have to fetch these upon the first subscribe to the this.stores. All other subscribes may use the same values returned from your http.get. To accomplish this we can use .shareReplay() to have all subscribers multicast to the same source and have it replay its previous values instead of re-invoking http.get

function getStores() {
  //return http.get<Store[]>(URL) 
  return Rx.Observable.from(['asdf', 'foo', 'bar']).delay(500);
}

const stores = getStores()
  .do(undefined, undefined, _ => console.log('retrieved values from http backend'))
  .shareReplay();
const $buttonClicks = Rx.Observable.fromEvent(document.getElementById('button'), 'click');

$buttonClicks
  .do(_ => console.log('CLICKED'))
  .switchMap(_ => stores
               .map((val, idx) => [val, idx])
               .filter(tuple => tuple[0] === 'foo')
               .map(tuple => tuple[1])
            )
  .subscribe(
    idx => console.log('got index of `foo`: ' + idx)
  );

The switchMap is a bit ugly (map/filter/map) because this example code does not utilise an array but instead single emissions. .toArray() can fix this. Depends on how you want to proceed with using the index (or value)

1 Comment

Thanks, this is perfect!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.