What is the best way to sort through observable JSON file responses?

In the midst of my angular project, I have been assigned the challenge of filtering a massive file based on the "_type" key, which can hold various values. My current objective is to initiate the filtration process for _type = "COMPETITION".

The structure of my model is outlined in a competition.model.ts file, appearing as follows:

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"
}

Take a look at my service class where I am endeavoring to execute this task:

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 ) { 
            if (responseData.hasOwnProperty(key)) {
              competitionsArray.push(
                 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;
      });
  }
}

I have included a snapshot of the results displayed on my console, but it fails to meet the intended outcome.

https://i.sstatic.net/Y0aL3.png

Answer №1

I have identified several issues in the code snippet:

  1. An attempt is being made to fetch the asynchronous variable this.loadedCompetitions synchronously, which is not possible. Asynchronous variables should always be accessed asynchronously. Consider using RxJS ReplaySubject multicast observable with buffer 1 to hold and emit the last value.

  2. Instead of manually looping through each item in the array to create a new array based on the _type === 'COMPETITION' property, utilize the Array filter function to filter out objects based on a condition.

...
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
    );
  }
}
  1. It is essential to subscribe to the loadedCompetitions variable to receive notifications from it. Use the RxJS takeWhile operator with Subject to close any open subscriptions in the ngOnDestroy hook of the component.
...
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
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

React typescript props not appearing as potential defined, even after implementing the '?' optional operator and '| undefined'

I've noticed that my linter has suddenly stopped flagging potentially undefined properties passed into my React components. For instance: interface BooleanTypeObject { prop1: true } interface MyComponentProps { disable ...

Setting up Zurb Foundation in a VueJS TypeScript project: Step-by-step guide

I'm currently facing a challenge involving the integration of Zurb Foundation v6.5.3 into a VueJS project that is TypeScript-based and was created using @Vue/CLI. The project already includes jQuery type definitions. In the code snippet below, you can ...

Determination of character array length

I'm looking for a way to determine the length of an array in C. The code I have is as follows: int i=0; char a[7]={0x00,0xdc,0x01,0x04}; int len=0; len = sizeof(a); printf("The Length is : %d", len); Is there a way to find the length of the array a ...

Developing an HTML table with the power of JavaScript and JSON

I am having difficulty creating an HTML table using JavaScript with JSON input. In my code, I'm using a placeholder in the HTML that will be filled by a innerHTML call in Javascript: for (var i = 0; i < json.data.length; i++) { listItem = json. ...

Resolving typescript error in my custom hook

Implementing this ResizeObserver hook in my project using typescript const useResizeObserver = () => { const [entry, setEntry] = useState<ResizeObserverEntry>(); const [node, setNode] = useState<Element | null>(null); const observer = ...

The onChange function in CustomSelect is triggering an endless loop of renders in a React application using TypeScript and Material-

Currently, I am working with a mui element called CustomSelect. It functions perfectly on desktop, however, the handleChange function from onChange only console logs once. On mobile (even in development mode), it renders 51 times before crashing and displa ...

MongoMemoryServer - Dealing with Unexpected Errors

Currently, I am conducting tests on a typescript express-mongoose app using jest, supertest, and mongo-memory-server. Interestingly, all the tests are passing successfully, but an error keeps popping up in every test involving mongo-memory-server. It see ...

Trouble securing an undefined value in a union type

Encountering an error with the code below that seems unexpected. TypeScript is flagging rules[name] as not being callable, which is true since it can be undefined. Even after guarding against this case, the same error persists. The issue is elaborated in t ...

A guide on using JOLT to swap out the outer curly braces for outer square brackets

How can I use JOLT transformation to replace the outer curly brackets with outer square brackets for the field filters? { "after":{ "import_id":912, "date":"2021-01-21 00:00:00.0", "filters& ...

Issues encountered during the configuration of Angular 8 Route (Auth) Guards

I recently attempted to incorporate Route Guards into my web application but encountered numerous errors along the way. Can anyone pinpoint where I might have gone wrong? My web app features various routes, one of which is a dashboard that requires protec ...

Using JSON Web Tokens for PHP authentication

Currently in the process of developing a 'social network' platform, with emphasis on creating the authentication module. Recently delved into the realm of JSON Web Tokens (JWT). 1) Initial understanding proposed that JWT's offer security du ...

Efficient JSON Representations for RESTful Collection Resources with Seamless Roundtripping

My Columns resource contains a collection of data. When making a GET request with Accept: application/json, it's not possible to directly return the collection, so I need to nest it within a property like this:- { "propertyName": [ { "Id": "Column ...

Mastering the use of npm and sails to create HTML-PDF files effortlessly

UPDATE: I am simplifying my question and will address any other concerns in separate posts if necessary. The initial post was too lengthy, hoping for a straightforward guide on utilizing sails to its fullest potential. Apologies. To begin with, my knowled ...

Unresolved issue with RxJS - Finalize not triggering

When attempting a logout request, I have encountered an issue where the same actions need to be dispatched regardless of whether the request is successful or fails. My initial plan was to utilize the finalize() operator for this purpose. Unfortunately, I ...

Is there a way to convert a JSONObject to a .csv file in GWT?

I'm brand new to GWT, so please forgive me if this is a basic question, but I can't seem to find the solution. I have a function that works fine and allows me to export a table as .xlsx file. Everything is going smoothly with this process. I am u ...

The function 'sendEmailVerification' is not a property of the type 'Promise<User>'

Hey there, I've been working on my ionic4 app and have encountered an issue with the sendEmailVerification function. The console is suggesting that I may have forgotten to use 'await'. Any ideas on how to resolve this? Thank you. import { In ...

experiencing issues with JSON parsing in Xcode

Having an issue with the following code: - (void)fetchedData:(NSData *)responseData { //parse out the json data NSError* error; NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; ...

Python JSON output using dump

I've been trying to write to a JSON file with a specific format. I've tried different methods to get the json.dump command to write the data in the same order as it is presented in the variables. I've received suggestions to use OrderDict an ...

Sending a form using AJAX causes the page to redirect

I have an input type="file" that triggers a form submission upon change. $(document).on("change", "#image-upload", function (e) { $.ajax({ url: '/BlogPost/UploadHomeReport', type: 'POST', data: $('#upload-i ...

Mastering the art of left joins with Doctrine's Query Builder

Currently, I am seeking a solution to execute a left join in Symfony using the query builder on a table under specific conditions: The content of Table cars: id image_uuids (stored as JSON) 1 ["fb9d77ab-4e8d-4d5e-b439-7cbc5009c230", &quo ...