Acquiring a collection of objects retrieved from a set of URLs using rxjs and typescript

I have an item to work with:

let DataObject = { 
  'item1' : './someitem1.json',
  'item2' : './someitem2.json',..
};

I want to fetch all items using RxJS and notify the subscriber only after all items have been fetched. Additionally, I want the subscriber to receive a result object with the original keys. For example:

let result = { 
  'item1' : fetchedData1,
  'item2' : fetchedData2,..
}

The code snippet that I currently have is as follows:

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/concatAll'; 
import 'rxjs/add/observable/of';

let observableBatch = [];
for (let key in DataObject) {
    observableBatch.push(
      this.http.get(DataObject[key]).map(
         (res) => {
             return Observable.of({[key] : res.json()})
         }
      )
    )
}
let mergedObs =Observable.forkJoin(observableBatch).concatAll();
mergedObs.subscribe((res) => {
    console.log(res);
});

However, I am encountering an error stating "Property 'subscribe' does not exist on type '{}[]'."

How can I resolve this error? Is there a more concise way to achieve the same functionality?

Answer №1

One great feature of using forkJoin is that you do not have to utilize concatAll. With forkJoin, it subscribes to all source Observables and waits until each one completes before emitting values, rather than Observables.

If you want to avoid creating an array of Observables beforehand or if the list of URLs is dynamic, you can implement a solution like this:

let UrlObject = {
    'url1' : './someurl1.json',
    'url2' : './someurl2.json',
    'url3' : './someurl3.json',
    'url4' : './someurl4.json',
    'url5' : './someurl5.json',
};

function httpRequest(key, url) {
    return Observable.of(url)
        .delay(1000)
        .map(response => [key, response.split('').reverse().join('')]);
}

Observable.from(Object.keys(UrlObject).map(key => [key, UrlObject[key]]))
    .flatMap(arr => httpRequest(arr[0], arr[1]))
    .toArray()
    .map(arr => {
        const obj = {};
        arr.forEach(respArr => obj[respArr[0]] = respArr[1]);
        return obj;
    })
    .subscribe(console.log);

The output to console would be:

{ url1: 'nosj.1lruemos/.',
  url2: 'nosj.2lruemos/.',
  url3: 'nosj.3lruemos/.',
  url4: 'nosj.4lruemos/.',
  url5: 'nosj.5lruemos/.' }

Take a look at the live demo here: https://jsbin.com/hozumix/2/edit?js,console

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 there a deeper philosophical rationale behind choosing to use (or not use) enums in TypeScript, along with string union types?

Recently, I delved into the world of enum and const enum in Typescript, causing some confusion. I grasped that const enum gets transpiled into simple values while regular enums do not. I also recognized certain distinctions between using string union type ...

Extract the content of a nested JSON object in ReactJS using map function

I am encountering an issue while attempting to map nested JSON data, specifically the error 'Element implicitly has an 'any' type'. The problem arises within the search component at: Object.keys(skills[keyName]).map() Below is the cod ...

An issue arises when using enums in TypeScript

Let's analyze this demonstration. Initially, an enum is created as follows: enum myEnum { a = 'a', b = 'b' } The next step involves creating a similar enum but with the addition of one more numeric value! This alteration is c ...

What is the best way to fetch the chosen item in an Angular select dropdown

I am working on a dropdown that populates with items of type ObjectA. item.component.html: <label>items list: <select formControlName="itemsCtl" (change)="onChange()"> <option *ngFor="let item of itemList" [value]="item">{{i ...

Instructions for adding a select dropdown feature in Angular 6 that includes a search filter. Additionally, tips on how to filter objects by their name property

I need to add an auto-complete feature in my Angular 6 app where the data is displayed as objects in a dropdown and filtered as we type. **template.html** <mat-form-field > <input matInput [matAutocomplete]="auto" [formControl]="customerFi ...

Incorporate a 'Select All' functionality into ion-select by adding a dedicated button

Looking for a way to set custom buttons on ion-select through interfaceOptions in ionic 4? HTML <ion-item> <ion-label>Lines</ion-label> <ion-select multiple="true" [(ngModel)]="SelectedLines" [interfaceOptions]="customAlertOption ...

How should one properly format an array of objects with elements that are different types of variations?

I am currently developing a versatile sorting module using TypeScript. This module will take in an array of data objects, along with a list of keys to sort by. Once the sorting process is complete, the array will be sorted based on the specified keys. To ...

Using `this` within an object declaration

I am encountering an issue with the following code snippet: const myObj = { reply(text: string, options?: Bot.SendMessageOptions) { return bot.sendMessage(msg.chat.id, text, { reply_to_message_id: msg.message_id, ...options }) ...

Error: Unable to locate Angular2 Custom Service

I have implemented a custom service to populate a list of people in my HTML. Below is the code for my custom service: app.peopleListService.ts import { Injectable } from '@angular/core'; import { Person } from "../model/peopleModel"; @Injecta ...

The ReactDOM.createPortal modal has been successfully mounted onto the DOM, however, there seems to be no visible content

This project utilizes TypeScript and Next.js. Within it, there is a Modal component: interface ModalProps { onCancelModal: () => void; onAcceptModal: () => void; acceptEnabled: boolean; isLoading?: boolean; title: string; } const Modal: Re ...

Using SCSS variables in TypeScript inside a Vue project

Has anyone had experience with importing SASS (scss) variables into JavaScript in a TypeScript Vue 3 project? // @/assets/styles/colors.scss $white: #fff; // @/assets/styles/_exports.scss @import "./colors.scss"; :export { white: $white; } <templat ...

Issues with type errors in authentication wrapper for getServerSideProps

While working on implementing an auth wrapper for getServerSideProps in Next.js, I encountered some type errors within the hook and on the pages that require it. Below is the code for the wrapper along with the TypeScript error messages. It's importan ...

Automatically dismiss modal upon submission

In the process of implementing a CRUD operation, I am trying to automatically close the modal upon submission. Using data-dismiss on the submit button only closes the modal without executing the functionality. What I need is for the functionality to execut ...

The optimal location to declare a constructor in Typescript

When it comes to adding properties in an Angular component, the placement of these properties in relation to the constructor function can be a topic of discussion. Is it best to declare them before or after the constructor? Which method is better - Method ...

What is the best approach to managing exceptions consistently across all Angular 2/ Typescript observables?

Throughout the learning process of Angular2, I have noticed that exceptions are often caught right at the point of the call. For example: getHeroes(): Promise<Hero[]> { return this.http.get(this.heroesUrl) .toPromise() ...

"Encountering an issue where attempting to set a property on an undefined variable, despite it being

I've been working on a timer app/component, but I'm running into an issue. The error message reads: Cannot set property startAt of undefined. I've defined it in my dashboard component, so I'm not sure where the problem lies. Any suggest ...

Is it possible for input properties of array type to change on multiple components in Angular 9?

Encountering an interesting issue that I need clarification on. Recently, I developed a compact Angular application to demonstrate the problem at hand. The puzzling situation arises when passing an Array (any[] or Object[]) as an @Input property to a chil ...

Inquiring about the application of spread argument in TypeScript

Here is some code I'm working on: import _ from 'lodash'; function test(num1: number, num2: number) { console.log(num1, num2); } test(..._.take(_.shuffle([0, 1, 2]), 2)); I encountered a TS2556 error while using the TS playground and ...

How to configure dynamic columns in material-table using React and TypeScript

My task involves handling a table with a variable number of columns that are generated dynamically based on the data received. To manage these columns, I have designed an interface that defines various properties for each column, such as whether it can be ...

Creating intricate mazes using canvas drawing techniques

I recently developed a maze generator as a personal project utilizing a graph. While the generation logic works perfectly, I am facing challenges when it comes to rendering the maze. In my approach, each cell is represented by an array of 4 edges where the ...