Отображение объекта JSON в наблюдаемый для использования с ngFor Angular

Я пытаюсь сопоставить объект JSON наблюдаемому интерфейсу, который я настроил в своем угловом приложении, я надеюсь, что после его сопоставления я смогу использовать его как вход для циклического просмотра ngFor.

К сожалению, я не верю, что я правильно настраиваю свою службу или, возможно, вызов службы.

Я получаю объект json, возвращаемый как один объект, но ngFor не выполняет должным образом циклический просмотр возвращаемых результатов, любая помощь в указании того, что я могу пропустить, будет принята с благодарностью.

// Интерфейс, к которому я пытаюсь получить доступ

export interface IProduct {
   name: string;
   description: string;
   price: number;
   category: string;
   image: string;
}

// Служба, которую я пытаюсь вызвать

private productList = new BehaviorSubject<IProduct[]|null>(null);
productListChanges$ = this.productList.asObservable();
constructor(private http: HttpClient) { }

getProds(): Observable<IProduct[]> {
     this.productList.next(null);
     return this.http.get<IProduct[]> 
                      ('http://localhost:4200/assets/data/products.json')
     .pipe(
        tap(data => this.productList.next(data)),
     );
 }

// Позвонить на сервис

productsList: IProduct[] = [];

this.productService.getProds().subscribe((response: any) => {
  this.productsList = response.products[0] as IProduct[];
  console.log(this.productsList);
});

// Попытка использовать ngFor с полученным объектом

<app-product *ngFor="let product of productsList" [prod]="product" ></app-product>

// Журнал консоли из сервисного вызова выводит следующее

logOutput из сервисного вызова

3 ответа

Попробуйте с асинхронным циклом с Observables.

<app-product *ngFor="let product of productsList | async" [prod]="product" ></app-product>

Как показывает вывод вашей консоли, productsList это объект, но ngFor ожидает массив.

Если вы можете изменить данные, это должно быть легко выполнимо изменить на массив ([...]) вместо объекта ({...}).

В противном случае у вас есть несколько вариантов преобразования структуры в коде в массив. Например, при использовании Object.values() Вы можете преобразовать вашу текущую структуру в массив. Кроме того, вы также можете использовать KeyValuePipe, доступную начиная с Angular 6.1. Также ответили здесь /questions/4569272/klyuch-dostupa-i-znachenie-obekta-ispolzuya-ngfor/4569286#4569286

Я вижу, что вы используете HTTP для обслуживания данных JSON, которые легко доступны как данные, поступающие из статического файла, существующего в вашей папке ресурсов. Я бы избегал HTTP-звонков для их обслуживания. Я реорганизовал ваш код как для обслуживания статических данных, так и для поддержки удаленного запроса данных с использованием одного и того же метода обслуживания. Это также должно помочь во время модульного тестирования, поскольку асинхронное тестирование - это кошмар.

// Changed the Interface to a class
export class Product {
   name: string;
   description: string;
   price: number;
   category: string;
   image: string;
}

// Create a sample-data.ts file
export const ProductListData: Array<Product> = [
    {
       name: 'ProductName',
       description: 'Description',
       price: '9.99', // Maybe should be a number type and not string
       category: 'Test Category',
       image: 'your url for testing'
    }
]

// In service... 
import { of } from 'rxjs';
import { ProductListData } from './sample-data';
useSampleData = false;

getProducts(): Observable<Array<Product>> {
    if (useSampleData) {
        // Use this is your want to serve static JSON
        return of(ProductListData); // of() turns your readily avialable object into an obeservable promise
    } else {
    // Get from actual HTTP as async
        return this.http.get<Array<Product>>('http://localhost:4200/api/your-endpoint-url');
    }
 }
 
 
// In you Component...
public productList: Array<Product> = [];

this.productService.getProducts().subscribe(
    productList => {
      this.productsList = productList;
    },
    err => {
        console.log('Error: ', err);
    }
);

Ваш шаблон не нуждается в изменении.

Другие вопросы по тегам