Как передать массив с объектами от провайдера на страницу? - PullRequest
0 голосов
/ 09 января 2019

У меня есть структура карты в провайдере, и я должен показывать значения из объектов карты в моем шаблоне. Мой провайдер store.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();
    url_request = "path/to/json";


  constructor(public http: HttpClient) {
  }

getRequest(callback){
    this.JsonStoresData.clear();
    this.http.get<JsonStoresDataInterface>(this.url_request).subscribe(data => {
        var json = data.data;
        for (var store of json.stores){
          if(store.polygon_id[0] != null){
            var obj = { name: store.name,
                        description: store.description,
                        floor: store.floor,
                        image: store.pic_info.src,
                        uid: store.uid }

            this.JsonStoresData.set(store.polygon_id, obj)
        }}
        callback(this.JsonStoresData);
    });
}

 getStoresRemote(){
    return new Promise(resolve => {
      //let def_key = this.defaultKey;
      this.getRequest(function(data){
          let storeArray = [];
          storeArray = Array.from(data.values());
          storeArray.sort((a,b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0));
          let storeName = storeArray.map(a => a.name);
          resolve(storeArray);
      });
  });

}

}

home.ts:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { MenuComponent } from "../../components/menu/menu";
import { StoresProvider } from './../../providers/stores/stores';

@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {

public buttonClicked: boolean = false;
public btnActive: string = "";
img;
description;
storeArray;

openStore(i) {
    document.getElementById('main').className += ' no-scroll';
    document.getElementById('card').className += ' active';
    this.buttonClicked = !this.buttonClicked;
    this.description =  this.storeArray[i].description;
    console.log(this.description);// Cannot read property 'description' of undefined
at 
        }

ionViewDidLoad() {
    this.storeArray = this.storesProvider.getStoresRemote();
    console.log('this.storeArray');
  }
constructor(public navCtrl: NavController, public storesProvider: StoresProvider) {
 }

}

home.html:

<ion-header>
    <menu></menu>
    <ion-title>stores</ion-title>
</ion-header>

<ion-content  no-padding>
        <ion-list class="list-card" *ngFor="let store of storeArray | async let i = index">
                <ion-item (click)="openStore(i)" >
                <span class="name">{{store.name}}</span> //got it ok 
                <span class="floor">{{store.floor}}</span>//got it ok 

                </ion-item>
        </ion-list>

</ion-content>

                <ion-card ion-fixed  id="card" class="big-card" >
                    <p>{{description}}</p> // cant get this
                </ion-card>

Ошибка: невозможно прочитать описание свойства неопределенного

Также вот как выглядит мой массив, переданный от провайдера: скриншот консоли Это нормально?

Мне нужно получить значения объектов из массива, переданного от провайдера, по индексу, который я получил из ion-list, но, возможно, есть другие способы сделать это?

1 Ответ

0 голосов
/ 09 января 2019

Ваш метод getStoresRemote возвращает обещание, и для разрешения этого обещания вы используете трубу angular async внутри шаблона. Таким образом, storeArray разрешается только внутри шаблона, который недоступен внутри контроллера.

Когда вы пытаетесь выполнить this.storeArray[i].description, контроллер знает только, что storeArray является обещанием (он не знает, что он на самом деле разрешен внутри шаблона), поэтому выдает ошибку Cannot read property 'description' of undefined.

Чтобы решить эту проблему, вы должны удалить async pipe из шаблона или передать весь объект store в метод openstore вместо i.

Решение 1

home.ts

openStore(i) {
    document.getElementById('main').className += ' no-scroll';
    document.getElementById('card').className += ' active';
    this.buttonClicked = !this.buttonClicked;
    this.description =  this.storeArray[i].description;
    console.log(this.description);
        }

ionViewDidLoad() {
    this.storesProvider.getStoresRemote().then(data => this.storeArray = data);
  }

home.html

 <ion-list class="list-card" *ngFor="let store of storeArray let i = index">
      <ion-item (click)="openStore(i)" >
          <span class="name">{{store.name}}</span> 
          <span class="floor">{{store.floor}}</span>
      </ion-item>
 </ion-list>

Решение 2

home.html

<ion-list class="list-card" *ngFor="let store of storeArray | async let i = index">
     <ion-item (click)="openStore(store)" >
         <span class="name">{{store.name}}</span> //got it ok 
         <span class="floor">{{store.floor}}</span>//got it ok 
     </ion-item>
</ion-list>

затем измените openstore() метод, подобный этому

openStore(store) {
    document.getElementById('main').className += ' no-scroll';
    document.getElementById('card').className += ' active';
    this.buttonClicked = !this.buttonClicked;
    this.description = store.description;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...