Is it possible to implement lazy loading for data in TypeScript classes?

Looking to optimize my Angular application's data structure when consuming a RESTful API. My goal is to only load necessary data from the server on demand.

For instance, if I have a collection of Building objects each with a set of tenant IDs in an array instead of full Tenant objects. This way, when listing buildings in the app, I can display basic details and fetch individual tenant information from the API asynchronously only when needed. It helps avoid fetching all tenants upfront for every building.

Is this a common approach in web applications? Struggling to find resources on this specific topic, especially implementations tailored for Angular.

Appreciate any insights or Angular-specific examples on implementing this strategy!

Answer №1

I've been pondering this same dilemma myself. Here are a few potential strategies:

  1. Load everything at once - Simply retrieve all the data from your REST server upfront, as you mentioned. While this is convenient, it may not scale well with nested data structures or large amounts of data. However, it could be suitable if the data is only used at a single nesting level and is relatively small for each object, or if performance and bandwidth concerns are minimal.

The other options explore asynchronous approaches to retrieving data, where the Building REST route returns the Building object along with a TenantsURL for accessing the tenant list.

  1. Lazy TypeScript getters: Conceal the variable behind a getter in your class:

    class Building {
    
        public constructor(private readonly httpService: HttpClient){}
    
        public get tenants(): Observable<Tenant[]> {
            return this.httpService.get<Tenant[]>([url here]);
        }
    
    }
    

    A drawback here is that using tenants in an HTML template will cause angular to call this getter function during each change detection step, potentially adding costs depending on latency and data size. Another downside is the requirement for the HttpClient Service (or a custom service) injected into your models, blurring the line between services and models.

  2. Standalone Get Function: A slight tweak to #2, creating a class method in your model that can be called:

    class Building {
    
        public constructor(){}
    
        public getTenants(httpService: HttpClient): Observable<Tenant[]> {
            return httpService.get<Tenant[]>([url here]);
        }
    
    }
    

    This shifts the responsibility for providing the "getter" service (HttpClient in this case) from model construction to whoever needs to access the tenants, such as an Angular component. You can then use an Async pipe in an HTML template to display the values, or subscribe in an Angular component. However, since this is a function, it will be invoked during every change detection cycle, impacting performance.

  3. Pipe: Create a custom async pipe, TenantPipe, allowing injection of necessary services to retrieve Tenant data from a Building (https://angular.io/guide/pipes). You can then apply the pipe on the Building in an HTML template to asynchronously fetch the list of tenants. By separating models from the async retrieval functionality, angular will execute the pipe only once per change detection cycle. While more focused on HTML templates, pipes can also be injected into component typescript for similar functionality.

  1. Service: Develop a service, TenantService, featuring a method
    getTenantFromBuilding(building: Building): Observable<Tenant[]>
    . Utilize this in your typescript components wherever needed. This approach mirrors #4 but encapsulates the functionality within a service rather than a pipe with injected services. More oriented towards Typescript, the returned value from the service can still be displayed in an HTML template.

Each approach carries its own advantages and drawbacks, so choosing the right one depends on the context at hand.

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

What is the best way to send data from a child component to a parent component in Angular 2?

I want to retrieve data from my child component, which contains a form in a popup. How can I pass all the details to the parent component? Here is the TypeScript file for my parent component: import { Component, OnInit } from '@angular/core' ...

Unable to employ a custom Typescript .d.ts file

Currently, I am delving into learning TypeScript and encountering a hurdle while attempting to define a class in a TypeScript definition file and then utilize it in a TypeScript file. The dilemma lies with a JavaScript "class" called "Facade," which serve ...

What could be causing the lack of updates to my component in this todo list?

Based on my understanding, invoking an action in MobX should trigger a rerender for the observer. However, when I call the handleSubmit method in my AddTask component, it doesn't cause the TaskList observer to rerender. Should I also wrap AddTask in a ...

Error: Ionic 2 encountered an error: Highcharts has produced Error #17 - learn more at www.highcharts.com/errors/17

I'd like to incorporate a highchart gauge in my project, but I'm encountering an issue: Uncaught (in promise): Error: Highcharts error #17: www.highcharts.com/errors/17 error I've been advised to load the highcharts-more.js file, but I&a ...

What is the best way to exclude an interface using a union type recursively in TypeScript?

I wish to recursively exclude types that are part of union types, and eliminate certain union types Here is an example. Normal and Admin should be considered as union types interface Admin { admin: never; } interface Normal { normal: never; } ...

Testing the use of rxjs fromEvent in Angular while mocking subscriptions

In the Angular component, I have an array of objects representing companies that are provided via @Input(). Upon loading this data, which is obtained from an HTTP request, I assign it to another variable called filteredList, which is used in an *ngFor dire ...

Obtain an array from JSON within Azure Data Factory with this simple guide

My current setup, although not functioning properly, consists of two pipelines: Retrieving API data to store in a lake: for each row in the metadata table in SQL, I make a call to the REST API and transfer the response (json files) to the Blob datalake. T ...

Angular Unit Test: Received 1 argument instead of the expected 3

Currently, I am in the process of unit testing an Angular application. This is my first time venturing into Angular Unit Testing. To save time, I downloaded the angular app from here. As a beginner in Unit Testing, I watched some informative videos on the ...

Which is more data-efficient: sockets or REST APIs?

I am looking for a way to maintain a constant connection to a server without relying on wifi. Since my IoT device will be located in an area without wifi coverage, I need to use a 3G module instead. In terms of data consumption efficiency, which protocol ...

Currency symbol display option "narrowSymbol" is not compatible with Next.Js 9.4.4 when using Intl.NumberFormat

I am currently utilizing Next.JS version 9.4.4 When attempting to implement the following code: new Intl.NumberFormat('en-GB', { style: 'currency', currency: currency, useGrouping: true, currencyDisplay: 'narrowSymbol'}); I ...

After selecting an item, the Next UI navbar menu seems to have trouble closing

Having trouble with the navbar menu component not closing when an option is selected from the menu. The menu does open and close successfully within the menu icon. I attempted to use onPress() but it doesn't seem to be working as expected. "use c ...

Returning multiple recordsets in SQL 2016 with JSON support

Trying to utilize MS SQL 2016 for fetching an array of JSON objects containing all table information. However, the query seems to be returning a duplicate array of record sets instead of just one with the queried data. var sql = require('mssql/msnode ...

What is the correct way to define types for higher-order class components in TypeScript?

I have developed a utility function that currently has an unused options parameter, and it returns a higher-order component wrapping function. How can I effectively define types on the component so that users of the wrapped component can visualize the typ ...

What is the process for running a continuous stream listener in a node.js function?

I am currently working with a file called stream.ts: require('envkey') import Twitter from 'twitter-lite'; const mainFn = async () => { const client = new Twitter({ consumer_key: process.env['TWITTER_CONSUMER_KEY'], ...

Accessing properties for objects with map-like characteristics

Many interfaces allow for arbitrary data, as shown below: interface Something { name: string; data: { [key: string]: any }; } The problem arises when trying to access or set values on objects with arbitrary keys in Typescript. let a: Something = { ...

Ways to categorize items retrieved from an HTTP request to the backend in Angular

When making a call to the backend using this http request: this.StudentEnrollment.getRecordsById(list.value.split(/[\r\n]+/)).subscribe(values => { this.studentObject = values; }); The studentObject is structured as shown below: { recor ...

The specific property 'splice' cannot be found within type 'T'

As I delve into working with TypeScript, an unexpected error arises: Property 'splice' does not exist on type 'T'. type Item = { name: string, body: string, imgOne: string, imgTwo: string, }[] // Another file contains this func ...

What should be done in the absence of any subscriptions?

Incorporating a generic HTTP service to encapsulate certain HTTP behaviors is part of our system. In case of an error, we include the error in a BehaviorSubject. I am contemplating on whether there is a method to display this error only if no one is subsc ...

What could be the reason for TypeScript allowing the injection of an invalid type?

I have the following objects and classes that demonstrate dependency injection: abstract class Animal { speak(): void {}; } class Dog implements Animal { speak(): void { console.log('Woof woof'); } } class Cat implements Ani ...

The NodeJS server is struggling to fetch post data sent from Angular

I've developed a backend server using NodeJS with Express. On the frontend side, I'm working with the latest version of Angular. When I post data (GPG file) to the NodeJS server and try to retrieve it in my NodeJS code to output it on the server ...