![](/img/trans.png)
[英]How to break a JSON file into a smaller json wrapped in an array using jq?
[英]How to filter an observable wrapped json file response?
我正在处理一个 angular 项目,我的任务是根据可以采用不同值的“_type”键过滤一个大文件。 现在我想先过滤 _type = "COMPETITION"。
我的模型是在一个如下所示的竞争.model.ts 文件中定义的:
export interface Competition {
product: { active: true };
schemaVersion: number; // 2,
status: string; // PUBLISHED",
comp: string; // "4fc16b10-b8b4-4a99-b9f1-842f0d8b8413",
_createdDate: number; // 1594249198,
discipline: string; // "TRAP [ACTA]",
categories: any; // ["OPEN", "LADIES", "JUNIOR", "VETERAN", "CLAYS_ONLY"],
host: string; // "2",
changeSet: number; // 257,
sync: number; // 155,
seq: number; // 120,
id: string; // "4fc16b10-b8b4-4a99-b9f1-842f0d8b8413",
_type: string; // "COMPETITION",
when: number; // 1597154400,
title: string; // "ACTA Self Nom Test"
}
这是我正在尝试实现的服务类:
import { Injectable, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/Operators';
import { Competition } from '../interfaces/competition.model';
@Injectable ({providedIn: 'root'})
export class CompetitionListService {
private loadedCompetitions: Competition[];
private url = '../../assets/data/program1.json';
constructor(private http: HttpClient) {}
public getCompetitions(): Competition[] { return this.loadedCompetitions; }
public fetchCompetition(){
return this.http
.get<Competition[]>(this.url)
.pipe(
map( (responseData) => {
const competitionsArray = [];
for (const key in responseData ) { // responseData is an object
if (responseData.hasOwnProperty(key)) {
// get the_type property
// if ( key.valueOf() === 'COMPETITION') {
competitionsArray.push(
// responseData[key]._createdDate,
responseData[key]._createdDate,
responseData[key]._type,
responseData[key].categories,
responseData[key].changeSet,
responseData[key].comp,
responseData[key].discipline,
responseData[key].host,
responseData[key].id,
responseData[key].product,
responseData[key].schemaVersion,
responseData[key].seq,
responseData[key].status
);
}
}
console.log(competitionsArray);
return competitionsArray;
})
)
.subscribe(competitions => {
console.log(competitions);
this.loadedCompetitions = competitions;
});
}
}
我在我的控制台上附加了结果的快照,这并没有真正实现我真正想要实现的目标。
我在这里看到多个问题
您正在尝试同步获取异步变量this.loadedCompetitions
。 这不可能。 所有异步变量都应该异步访问。 您可以使用带有缓冲区 1 的 RxJS ReplaySubject
多播可观察对象来保存和发出最后一个值。
您不必手动遍历数组的每个项目并使用_type === 'COMPETITION'
属性创建一个新数组。 您可以使用数组filter
功能根据条件过滤掉对象。
...
import { Observable, ReplaySubject } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable ({providedIn: 'root'})
export class CompetitionListService {
private loadedCompetitions: ReplaySubject<Competition[]> = new ReplaySubject<Competition[]>(1);
private url = '../../assets/data/program1.json';
constructor(private http: HttpClient) {
this.fetchCompetition(); // <-- triggers the request and pushes value to `loadedCompetitions`
}
public getCompetitions(): Observable<Competition[]> {
return this.loadedCompetitions.asObservable();
}
public fetchCompetition() { // return nothing here
this.http.get<Competition[]>(this.url).pipe(
map(res => res.filter(item => item['_type'] !== 'COMPETITION'))
).subscribe(
res => this.loadedCompetitions.next(res),
err => console.log(err) // <-- handle error
);
}
}
loadedCompetitions
变量以从中获取通知。 我已经使用 RxJS takeWhile
运算符和Subject
来关闭组件的ngOnDestroy
钩子中的任何打开的订阅。...
import { Observable, Subject } from 'rxjs';
import { takeWhile } from 'rxjs/operators';
export class SomeComponent implements OnInit, OnDestroy {
private close$ = new Subject<any>(); // <-- use to close open subscriptions
constructor(private competitionListService: CompetitionListService) { }
ngOnInit() {
this.competitionListService.loadedCompetitions.pipe(
takeWhile(this.close$)
).subscribe(
res => {
console.log(res);
// other statements that depend on `res`
}
);
}
ngOnDestroy() {
this.close$.next(); // <-- close open subscriptions
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.