Tips for preventing the use of Observable within another Observable

My service makes an http request that returns Observables of headlines. The code in my servise.ts file looks like this:

servise.ts

get(sort: string): Observable<Response> {
    return this.http.get<any>(this.url, {...});
})

delete(id) {
  return this.http.delete(`${this.url}/${id}`, {...});
}

In my component, I have a function that sets this.headlines from the service get request. Here is how it is implemented:

interface IRes {
  searches: {
    label: string,
    id: number,
    value: string,
    ...
  }
}
headlines = [];

loadHeadlines() {
  this.service.get(data).subscribe((res: IRes) => this.headlines= res.headlines);
}

At times, I receive headlines with empty labels that I don't want to display. Hence, I need to filter them out and send a delete request for these headlines. I attempted the following approach (the concept was to use .pipe before subscribe and call another subscribe inside).

Here is the code snippet:

loadHeadlines() {
  this.service.get(data)
    .pipe(
      map(res: IRes => {
        res.headlines.filter(headline => !!headline.label.trim())
          .forEach(headline => this.service.delete(headline.id).subscribe())
      })
    )
    .subscribe((res: IRes) => this.headlines= res.headlines);
}

However, I am uncertain if this is the best approach. What would be a more effective method in this scenario?

Answer №1

If you're looking to manipulate observables in Angular, consider implementing the RxJS `switchMap` operator to transition from one observable to another and using the `forkJoin` function to merge multiple observables. Additionally, utilize the `iif` function with `of` to determine if there are any empty `headline` elements that need to be removed.

However, it appears that there may be some confusion regarding the current condition being used. It seems like all `headline` elements with an empty `label` property are being removed while invoking `delete` on the remaining elements. This essentially results in calling `delete` on all valid elements, which might require some adjustment.

You can try the following approach:

import { iif, forkJoin, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

loadHeadlines() {
  this.service.get(data).pipe(
    switchMap((res: IRes) => {
      const emptyHeadlines = res.headlines.filter(headline => !headline.label.trim()); // Filter headlines with empty labels
      const deletes$ = forkJoin(
        emptyHeadlines.map(headline => this.service.delete(headline.id))
      ).pipe(
        map(_ => ({     // Map back to return only headlines with defined `label`
          ...res,
          headlines: res.headlines.filter(headline => !!headline.label.trim())
        }))
      );
      return iif(
        () => !!emptyHeadlines.length,
        deletes$, // Execute delete action only if there are empty headlines 
        of(res)   // Forward the response if no empty headlines
      );
    })
  ).subscribe(
    (res: IRes) => this.headlines = res.headlines,
    (error: any) => console.log(error)
  );
}

Answer №2

It's not advisable to use !!headline.label.trim() in this scenario, as the double negation will remove all headlines that are NOT empty. Additionally, the map function should be replaced with a tap.

Here is the corrected pipe:

this.service.get(data).pipe(
    tap(headlines => headlines.filter(headline => !headline.label.trim()).forEach(
        headline => this.service.delete(headline.id)
    )),
    map(headlines => headlines.filter(headline => !!headline.label.trim()))
).subscribe(headlines => this.headlines = headlines);

In a real-world scenario, it would be preferable to handle this on the backend. However, opinions may vary as there is no definitive right or wrong approach.

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

Is it possible for web browsers to accommodate various HTML5 pattern regexp functionalities?

A basic regular expression pattern was implemented in a payment form on our website for customers: <input type="text" pattern="(|\$)[0-9]*(|\.[0-9]{2})" title="Please enter a valid number in the amount field" required> This pattern ...

Generating Words using JavaScript

I have been working on creating a word generator that prompts the user to input ten strings and then outputs a randomly selected one. However, instead of displaying the user input string, it is currently generating a random number. I am not encountering an ...

Is it possible to utilize a component's property as an argument for a method in Angular 6?

Within my Angular 6 application, I have a method designed to alter a property of my component. The scenario is as follows: ... value: number = 10; changeValue(v) { return v = 100; } ... Upon invoking this method with the component's property: this. ...

Service update causing $scope in Ionic Angular Cordova to remain stagnant

As a newcomer to Angular, I've been working on a project to create an app that can answer questions, select images, and send data to the server. I'm facing some challenges with updating the scope properly when a user selects an image. It seems l ...

Adding JSON to the data attribute within a set of DOM elements

I am in the process of developing a website dedicated to recipes, where I am using a Mustache.js template to load recipe information from a JSON file. The structure of my JSON file is as follows: { "recipes":[ {"name": "A", preparationTime: "40min", "serv ...

Guide on utilizing substring string functions in the updated version of Selenium IDE

I am facing a challenge with extracting the word "Automation" from a given string "Welcome to the Automation World" using Selenium IDE Record and Play feature. I have tried using the execute script command, but it doesn't seem to be working as expecte ...

What is the best way to organize information in a table based on the date

This is my data table https://i.stack.imgur.com/1DNlj.png in the displayed table, the registration dates are sorted with the oldest date at the top. However, I aim to have the newest data displayed first. Below is the code snippet I am using: this.dataSo ...

Pause until the user selects either the confirm or deny option before proceeding with the next action

As a beginner in Angular, I am seeking help with my code structure. I have three files: WarningComponent (which displays a warning modal using Bootstrap), modalService (responsible for opening modals), and votingComponent. Within the votingComponent, ther ...

Is there a way to properly validate the innerText of a multiline form field in SharePoint?

I'm facing an issue with a code snippet related to my problem. The output from console.log(field1[0].innerText); seems correct, but the if statement validation is always resulting in false. I've attempted various types of string validations like ...

What is the correct way to implement "next-redux-wrapper" with "Next.js", "Redux-ToolKit" and Typescript?

Currently, I am integrating RTK (redux-toolkit) into my Next.js App. I am facing an issue while trying to dispatch an AsyncThunk Action within "getInitialProps". During my research, I came across a package named "next-redux-wrapper" that allows access to t ...

Issue with parsing an empty array in a Discord bot built with Node.js

Within this API, there exists an empty array marked with a red underline. Sometimes it's void of content, but other times it contains data. My goal is to display Item Spells: there are no effects on this item. when the array is empty. However, instead ...

The function .innerHTML is not functioning correctly, at least in my opinion

When I utilize .innerHTML to insert text into a textarea, the script stops functioning if I manually begin editing the text in the textarea. Here is the code snippet: (function($){ addPort = function(name) { switch(name) { case 'name1': ...

Issue with Angular2 wysiwyg component failing to submitThe Angular2

I'm currently in the process of familiarizing myself with angular2 by developing a sleek wysiwyg component. However, I seem to have reached an obstacle at this point. Below is the code I've been working on: The form that I am utilizing for testi ...

Link AngularJS service array length property to the controller's scope through binding

I am attempting to connect the length of an array from another service to my controller's scope in the following manner: app.controller('TestCtrl', function ($scope, safePostService) { $scope.count = safePostService.queue.length; $ ...

Unable to display objects in the console window debugger for debugging purposes

When attempting to print the objects in the console window using the code below, I am receiving an "Undefined" error message. Any advice on how to resolve this issue? var details = [ { name:"Anita", age:"20" },{ name: "H ...

Tips for retrieving a value returned by a Google Maps Geocoder

geocoder.geocode( { 'address': full_address}, function(results, status) { lat = results[0].geometry.location.lat(); lng = results[0].geometry.location.lng(); alert(lat); // displays the latitude value correctly }); alert(lat); // does ...

Although AJAX $.post functions properly in the View, it seems to encounter issues when relocated to a separate .js file. Interestingly, all other JQuery functions work

I have recently delved into MVC, JQuery, and AJAX, and encountered a perplexing issue. After completing the initial development of a practice website, I dedicated time to enhance the interactivity using JQuery. Everything was functioning smoothly until I ...

Configuring servers for contemporary JavaScript applications

In search of a solution that would enable server settings to be stored in a separate config file from the JS application, allowing for flexibility between development and production modes. The goal is to have the server replace the config file with an upda ...

Live updates are shown in a format similar to a friend feed or the top tweets on Twitter

I'm currently utilizing PubSubHubbub to obtain the latest updates from the feed. Once the callback URL receives an update, it should be displayed on the webpage in a format similar to Friend Feed or Twitter's top tweets (with content moving down ...

Loading Angular Controller in a dynamic fashion

I am attempting to dynamically load controllers using ocLazyLoad: $ocLazyLoad.load('./ctrls/login.js'); However, I am encountering an error stating: The controller named 'loginCtrl' is not registered. angular.module('opt ...