How to get objects by map key?


#1

I have to get json through provider and save it in map where the key is “id” and other values is objects. This is my json:

{
    "data": {
        "stores": [{
                "description": "a1",
                "name": "b1",
                "id": ["_0010008"]
            },
            {
                "description": "a2",
                "name": "b2",
                "id": ["_0010007"]
            }
        ]
    },
    "message": "",
    "status": "ok"
}

This is my provider.ts:

import {
    HttpClient
} from '@angular/common/http';
import {
    HttpClientModule
} from '@angular/common/http'
import {
    Injectable
} from '@angular/core';
import 'rxjs/add/operator/map';
import {
    JsonStoresDataInterface
} from './../../providers/stores/stores';

/*
  Generated class for the StoresProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class StoresProvider {
    private JsonStoresData = new Map([]);
    defaultKey = "_0010008";
    url_request = "path/to/json";

    constructor(public http: HttpClient) {}

    getStoresRemote(s) {
        this.http.get < JsonStoresDataInterface > (this.url_request).subscribe(data => {
            var json = data.data;
            for (var store of json.stores) {
                var str = id[0];
                var arr = {
                    name: store.name,
                    description: store.description,
                }

                this.JsonStoresData.set(str, arr)
            }
        });

        console.log(this.JsonStoresData);
        console.log(this.JsonStoresData.get(this.defaultKey));
    }
}

console.log(this.JsonStoresData) is OK:

console.log(this.JsonStoresData.get(this.defaultKey)) is not OK:

Undefined

Whats wrong? And how to get objects by map key?


#2

I think this taxonomy of future-related functions might be helpful in clearing up what is going on. What I would do here is something along these lines:

export interface Store {
  description: string;
  name: string;
}

export interface StoreMap {
  [id: string]: Store;
}

interface WireStore extends Store {
  id: string[];
}

interface WireStores {
  stores: WireStore[];
}

interface WireStoreResponse {
  data: WireStores;
  message: string;
  status: string;
}

stores(): Observable<StoreMap> {
  return this._http.get<WireStoreResponse>(this.url).pipe(
    map(wsr => {
      let rv: StoreMap = {};
      wsr.data.stores.forEach(ws => {
        rv[ws.id[0]] = {description: ws.description, name: ws.name};
      });
      return rv;
    }));
  }

The subscription happens outside the provider, and in there everything about the StoreMap should be as you expect.