Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Processing a complex object by http get in Angular 6

I do not understand how to handle the object I subscribe to. The object is the following structure:

{
  data:{
       date: "2018-02-20 13:10:23",
       text: "Описание",
       id: 1,
       items: [
              0: {
                 date: "2018-02-20 13:10:23",
                 text: "Описание",
                 images: [
                         0: "image1.jpg",
                         1: "image2.jpg"
                         ],
                 name: "Изображения",
                 type: "images"
                 },
              1: {
                 date: "2018-02-20 13:10:23",
                 text: "Описание",
                 image: null,
                 type: "video",
                 url: "https://www.youtube.com/embed/v64KOxKVLVg"
                 }
              ]
       }
}

I make an appeal through the service:

import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
@Injectable()
export class VideoService {
    constructor(private http: HttpClient) {}

    getVideoTape() {
        return this.http.get(`http://ip_adress/api/v1/mixed_galleries/1`);
    }
}

There is an interface model:

export class VideoListModel {
    constructor(
        public created_at: string,
        public description: string,
        public id: number,
        public items: any[],
        public name: string
    ) {}
}

And I do the processing in the component:

import {Component, OnDestroy, OnInit} from '@angular/core';
import {Observable, Subscription} from 'rxjs';
import {filter} from 'rxjs/operators';
import {VideoService} from '../shared/services/video.service';
import {VideoListModel} from '../../shared/models/video-list.model';

@Component({
  selector: 'app-video-index',
  templateUrl: './video-index.component.html',
  styleUrls: ['./video-index.component.scss']
})

export class VideoIndexComponent implements OnInit, OnDestroy {
    private videoTape = [];
    private _subscription2: Subscription;

    constructor( private videoService: VideoService ) { }

  ngOnInit() {
      this._subscription2 = this.videoService.getVideoTape()
          .subscribe((data: VideoListModel[]) => {
          this.videoTape = data;
          console.log(this.videoTape);
      });
  }

    ngOnDestroy() {
        this._subscription2.unsubscribe();
    }

}

The task is to make a selection from objects by type: "video". Through AJAX + jQuery did it without problems, and in Angular I'm relatively new. Shoveled a bunch of video lessons yesterday, but nowhere are examples of filtering such complex objects.

Construction:

this._subscription2 = this.videoService.getVideoTape()
          .pipe(filter((data: VideoListModel[]) => data.items.type === 'video'))
          .subscribe((data: any) => {
              this.videoTape = data.data;
              console.log(this.videoTape);
          });

does not work. The result is an error saying "Property 'items' does not exist on type 'VideoListModel []'". Intuitively, I understand that the matter is most likely in the interface, but I can not understand how to modify the interface so that the filtering works correctly. If someone encountered filtering complex objects, tell me please how to solve this problem.

like image 494
Artemy Khodorev Avatar asked May 25 '18 08:05

Artemy Khodorev


People also ask

What does HTTP GET return in angular?

Use the HttpClient.get() method to fetch data from a server. The asynchronous method sends an HTTP request, and returns an Observable that emits the requested data when the response is received. The return type varies based on the observe and responseType values that you pass to the call.

What type does HttpClient get method return?

Default responseType of HttpClient. get() method is “json”. Every http response contains http response headers and body. With the use of observe option we can specify whether we want to access complete http response object or actual body.

What is HTTP request in angular?

HttpRequest represents an outgoing request, including URL, method, headers, body, and other request configuration options. Instances should be assumed to be immutable. To modify a HttpRequest , the clone method should be used.

What is HttpClient module in angular?

What Is HttpClient? HttpClient is a built-in service class available in the @angular/common/http package. It has multiple signature and return types for each request. It uses the RxJS observable-based APIs, which means it returns the observable and what we need to subscribe it.


1 Answers

You don't have an array of VideoModels but an array of items in an object. Piping the whole content to a filter lets you filter items out of arrays, but you have an object. You could try the following workaround:

Create an interface like this

interface Item {
  date: Date;
  text: string;
  images: string[];
  name: string;
  type: string;
}

export interface VideoModel {
  data: {
    date: Date;
    text: string;
    id: number;
    items: Item[];
  }
}

Then you can use HttpClient in your Service as follows

import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
[...]

getVideoTape(): Observable<VideoModel> {
  return this.http.get<VideoModel>(url).pipe(
    map(model => {
      const items = model.data.items.filter(item => item.type === 'video');
      model.data.items = items;
      return model;
    }),
    catchError(error => console.error(error))
  );
}

Pay attention to your images array, as it isn't valid json, string[]? Wouldn't it be better to filter the types serverside in order to reduce traffic?

like image 185
Felix Lemke Avatar answered Nov 03 '22 06:11

Felix Lemke