Strategies for dynamically appending data to `from([urls])` using RxJS

const dataResults = [];
from(generateMoreUrls())
    .pipe(
     mergeMap( url => fetch(url), 4) 
  ).subscribe(dataResult => {
    dataResults.push(dataResult);
 });


function generateMoreUrls() {
  let additionalUrls = [];
  for(let i = 101; i <= 200; i++) {
     additionalUrls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
  }
  return additionalUrls;
}

Is there a way to add more urls to from in order to obtain additional data?

Answer №1

If you want to store and push URLs using BehaviorSubject, simply create a BehaviorSubject instance for urls and then use urls.next(..newUrl) to add items to the stream.

import { BehaviorSubject, of } from 'rxjs'; 
import { map,mergeMap } from 'rxjs/operators';


const urls=new BehaviorSubject(null)

const results = [];
function generateUrl() {
  for(let i = 1; i <= 9; i++) {
     urls.next(`https://jsonplaceholder.typicode.com/todos/${i}`);
  }
}

urls.pipe(
     mergeMap( url => fetch(url).then(res=>res.json()).catch(e=>e)

     , 4) 
  ).subscribe(result => {
    results.push(result);
    console.log(results)
 });

generateUrl()


setTimeout(()=>urls.next(`https://jsonplaceholder.typicode.com/todos/10`),2000)

https://stackblitz.com/edit/rxjs-xw9dft

Answer №2

Mixing an action stream (such as adding an action) with your data stream allows for a seamless flow of adding items to your stream by incorporating them into the action stream.

Here is a customizable example that showcases this concept:

// Retrieve all products
products$ = this.http.get<Product[]>(this.productsUrl)
    .pipe(
      tap(data => console.log('Products', JSON.stringify(data))),
      catchError(this.handleError)
);

// Action Stream
private productInsertedSubject = new Subject<Product>();
productInsertedAction$ = this.productInsertedSubject.asObservable();

// Merge the streams
productsWithAdd$ = merge(
    this.products$,
    this.productInsertedAction$
 )
   .pipe(
       scan((acc: Product[], value: Product) => [...acc, value]),
       catchError(err => {
           console.error(err);
           return throwError(err);
       })
 );

 addProduct(newProduct: Product) {
     this.productInsertedSubject.next(newProduct);
 }

To add more items (in this case, products), simply utilize the addProduct function and provide the necessary input.

LATEST UPDATE: I have adjusted the code above to better suit your specific requirements:

results = [];

// Data stream
urls$ = from(this.generateUrls());

// Action Stream
private newUrlSubject = new Subject<string>();
newUrlAction$ = this.newUrlSubject.asObservable();

// Merge the streams
urlsWithAdd$ = merge(
    this.urls$,
    this.newUrlAction$
)
   .pipe(
       tap(url => console.log('url:', url)),
       mergeMap(url => this.http.get(url), 4),
       tap(result => this.results.push(result))
);

constructor(private http: HttpClient, ) {
    this.urlsWithAdd$.subscribe();
}

generateUrls() {
    let urls = [];
    for (let i = 1; i <= 20; i++) {
        urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
    }
    return urls;
}

addUrl(newUrl: string) {
    this.newUrlSubject.next(newUrl);
}

onClick() {
    this.addUrl(`https://jsonplaceholder.typicode.com/todos/42`);
}

The complete code can be accessed here: https://stackblitz.com/edit/angular-rxjs-adding-items-deborahk

PLEASE NOTE: The use of fetch was not viable due to its promise-based nature, unlike Observables. However, you could explore alternatives like from(fetch(...))?

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

Using Angular NgUpgrade to inject an AngularJS service into an Angular service results in an error message stating: Unhandled Promise rejection: Cannot read property 'get' of undefined; Zone:

I have noticed several similar issues on this platform, but none of the solutions seem to work for me. My understanding is that because our Ng2App is bootstrapped first, it does not have a reference to $injector yet. Consequently, when I attempt to use it ...

What is the best way to incorporate a module from an external 'include' folder in your code?

Within my project's tsconfig.json, I have specified the following: "include": [ "src/**/*", "generated**/*" ] In the directory, there exist two files named src/main.ts and generated/data.json. The task at hand is to be able to successfully ...

Using TypeScript with MongoDB aggregation

Recently, I've been working on a User model with the goal of achieving generic aggregation. Essentially, I want to be able to pass an array of objects to a function and have it execute smoothly. Let me provide you with a snippet of the getUser functi ...

Why is it necessary to define a property outside the constructor in Typescript, when in Javascript I wouldn't have to do that?

When working with Javascript, creating a class like the one below allows us to avoid declaring and initializing a property named logs outside of the constructor: class Logger { constructor() { this.logs = []; } } However, transitioning to TypeScri ...

Is it feasible to utilize the redirectTo function alongside the children parameter?

It's important to note that in the latest version of @angular/router 3.0.0-rc.1, you are unable to use the redirectTo parameter if you are also utilizing the children parameter. In some scenarios, such as my own, there may be a need for this function ...

Adding a function to an interface in React Typescript: A step-by-step guide

My current setup is structured like this: enum AnimeType { Action = "ACTION" Comedy = "COMEDY" } const animeTypes: {[key: string]: AnimeInfo} = { "ACTION": { info: "Action-packed fun", co ...

Retrieving an array of objects from an API and attempting to store it using useState, but only receiving an empty

I have been working on fetching data from an API, storing it in Redux store initially, and then attempting to retrieve it using useSlector to finally save it in local state. Despite getting the data when I console.log it, I am unable to successfully store ...

When I refresh the page in Angular2, the router parameters do not get loaded again

When loading my application on routers without parameters, everything is normal. However, when trying to use a router with params, the application fails to load. For example: localhost:3000/usersid/:id The code for the router is as follows: const appRou ...

Stop fullscreen mode in Angular after initiating in fullscreen mode

Issue with exiting full screen on Angular when starting Chrome in full-screen mode. HTML: <hello name="{{ name }}"></hello> <a href="https://angular-go-full-screen-f11-key.stackblitz.io" target="_blank" style=& ...

Steps for modifying the settings of an express function

According to the documentation, the expected input types for the express Request.send function are defined as (property) Response<any>.send: (body?: any) => Response<any> in the VS Code editor. Is it possible to modify this function to acc ...

Determining if an object aligns with a specific type in Typescript

Hey there, I've got a little dilemma. Imagine I have a type called A: type A = { prop1: string, prop2: { prop3: string } } Now, let's say I'm getting a JSON object from an outside service and I need to check if that JSO ...

Sundays and last days are excluding React-big-calendar and dayjs longer events from being displayed

I've encountered a bug in my calendar view implementation. Long events are not displaying on Sundays or the ending day. Please refer to this image for reference: https://i.stack.imgur.com/V0iis.png Event details: Start time: Mon Aug 07 2023 15:44:00 ...

Encountering a "Missing Access" error on the Discord.js API when trying to register my slash commands

Three years ago, I created a small Discord bot in Typescript that is now present on over 80 guilds. Recently, I made the decision to update it from discord.js-v12.3.1-dev to discord.js-v13.6, while also integrating the popular slash commands feature. Howe ...

405 we're sorry, but the POST method is not allowed on this page. This page does

I'm currently working on a small Form using the kit feature Actions. However, I'm facing an issue when trying to submit the form - I keep receiving a "405 POST method not allowed. No actions exist for this page" error message. My code is quite st ...

Passing data and events between components in React

I'm currently working on developing a dashboard app that includes a basic AppBar and a drawer. I based my design on this Demo. https://codesandbox.io/s/nj3u0q?file=/demo.tsx In the Demo, the AppBar, Drawer, and Main content are all contained within ...

Can anyone provide a workaround for bypassing ts 2339 error in order to access class methods? Alternatively, is it feasible to define class methods outside of the class in typescript?

My plan is outlined below class A { constructor() { bind(this); } hello(){ this.method1(); // <-- I will get error at this line saying method one does not exist on typeOf A } } function bind(thisReference) { function method1() { ...

typescript, generate a new type by merging option values

In typescript I am faced with a challenge. I have a type called A: interface A { a1: string; a2: int; } As well as another type called B: interface B { b1: number } Now, my goal is to create a new type: interface AB { a1?: string; a2? ...

Troubleshooting property assignment issues within an Angular service

I have created a simple injectable service in TypeScript for Angular 4. This service is designed to fetch a JSON file from the network and store the data as an array in its property called data. Other classes can then access this data using the method getD ...

Guidelines for implementing more rigorous type checks in TypeScript:

I am looking to enhance the code validation process and eliminate any implicit 'any' types. To achieve this, I have set "strict": true in my tsconfig.json. { "compilerOptions": { "target": "ES5", ...

Executing RxJS calls in a sequential manner while allowing inner calls to operate in

I want to achieve a scenario using rxjs where a group of http calls are made with the value returned from a previous call. The inner calls should run in parallel, while still being able to return the value from the first call as soon as it's available ...