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.
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.
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.
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? 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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With