What is the best choice for storing data in my Angular2+ component: an object or an observable?

If I were to create an angular2+ component that fetches data from an API and displays its name, which approach would be considered more idiomatic?

Initial Strategy: Using thing as an object

In this scenario, the component subscribes to a websocket observable and updates its own thing object accordingly. If child components are utilized, a Thing will be passed as an input.

interface Thing { name: string }

@Component({
  selector: 'app-thing',
  template: '<h1> {{ thing?.name }} </h1>',
})
export class ThingComponent implements OnInit {
  public thing: Thing

  constructor(
    private route: ActivatedRoute,
    private thingService: ThingService,
  ) {}

  public ngOnInit() {
    this.route.params.subscribe(params => {
      this.thingService.get(params.id).subscribe(({thing}) => {
        this.thing = thing
      })
    })

    this.thingService.socketObservable().subscribe(newThing => {
      console.log('Thing has been updated !')
      this.thing = newThing
    })
  }
}

Alternative Approach: Treating thing as a Subject

This time, instead of using an object like thing: Thing, we opt for thing: Subject<Thing>. The template now employs the async pipe, providing child components with an observable rather than a direct Thing object.

interface Thing { name: string }

@Component({
  selector: 'app-thing',
  template: '<h1> {{ (thing | async)?.name }} </h1>',
})
export class ThingComponent implements OnInit {
  public thing: Subject<Thing>

  constructor(
    private route: ActivatedRoute,
    private thingService: ThingService,
  ) {}

  public ngOnInit() {
    this.thing = new Subject<Thing>()

    this.route.params.subscribe(params => {
      this.thingService.get(params.id).subscribe(({thing}) => {
        this.thing.next(thing)
      })
    })

    this.thingService.socketObservable().subscribe(newThing => {
      console.log('Thing has been updated !')
      this.thing.next(newThing)
    })
  }
}

Both versions appear functional on the surface. However, it's unclear whether they are equivalent beneath the surface. Any thoughts on whether the first or second approach is preferable?

Answer №1

Considering the stream nature of Socket, using Subject may be more appropriate in this scenario. However, the choice often comes down to your personal coding style preferences. If you are comfortable with reactive programming, opting for reactive solutions may be the way to go.

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

Concealing applicationId and clientToken in Datadog

I'm currently using an Angular application and I've integrated it with the Datadog application to utilize Session and Replay (RUM). However, I am concerned about the security of my sensitive information such as applicationId and clientToken. Is t ...

Troubleshooting Angular and Auth0: Understanding the issue with loginWithRedirect() always returning isAuthenticated$ as false

I have previously posted this issue on the Auth0 Community Help Forum, but I am yet to receive a response despite posting it 2 weeks ago. Here is the link to my original post: Currently, my setup includes angular/cli 15.1.1 and auth0/auth0-angular 2.0.1. ...

Angular form: Choose an option by selecting it and clicking on a button

I need help with my Angular form. I want to allow users to select a value when they click on a button. How can I achieve this? page.html <div *ngFor="let product of products; index as i"> <button (click)="chooseProduct(i)">{{product.name} ...

Yarn Plug'n'Play was unable to locate the module during the next build

Currently, I am in the process of developing a Next.js project with yarn's Plug'n'Play feature. In this project, I have created several pages and added various packages, including mathjs: '^10.3.0' to assist me in parsing user inpu ...

The Alert dialog in Shadcn will automatically close upon clicking the trigger from the dropdown menu

It seems like other people have encountered this issue, but they all used the alert dialog in the same file. I attempted to open the alert dialog using "" and included a dropdownmenuitem with 'delete' inside it. However, when trying to open the ...

What is the best way to only buffer specific items from an observable source and emit the rest immediately?

In this scenario, I have a stream of numbers being emitted every second. My goal is to group these numbers into arrays for a duration of 4 seconds, except when the number emitted is divisible by 5, in which case I want it to be emitted immediately without ...

The TypeScript type for a versatile onChange handler in a form

Let's skip the function declaration and dive into writing the current types for state, and the state itself. type BookFormState = { hasError: boolean; } BookForm<BookFormState> { ... state = { hasError: false }; Next, inside the class ...

How is it possible that TypeScript does not provide a warning when a function is called with a different number of arguments than what is expected?

I am working on a vanilla JavaScript project in VS Code and have set up jsconfig.json. Here is an example of the code I am using: /** * @param {(arg: string) => void} nestedFunction */ function myFunction(nestedFunction) { // Some logic here } myFu ...

Conversion of UTC timestamp to a timestamp in the specified timezone

this.selectedTimezone="Pacific/Kiritimati"; //this value will come from a dropdown menu These records represent the data.body returned by an API call. Iterating through each record in the dataset: { We are creating a new Date object based on the ...

How can I showcase an SVG icon received in base64 format using an img tag?

Having trouble displaying SVG/base64 encoded images through the img tag. Here is the issue at hand: Receiving iconData (as a string) from the server. Attempting to display it in my component. No issues with step 1. Encountering a broken image sign with s ...

An error occurred when trying to access object references within a function

Here is a snippet of my code: const fn1 = (param1: string, param2: string, param3: string): Promise<void> => {return new Promise()} const fn2 = (param1: string, param2: string): void => {return} const options = { option1: fn1, option2: ...

Which specific version of @angular/material should I be using?

After starting a new project, I encountered an issue while trying to install ng add @angular/material. The error message received was: # npm resolution error report While resolving: @angular/<a href="/cdn-cgi/l/email-protection" class="__cf_email__ ...

Is it possible to use AngularJS promise scheduling with `async`/`await` syntax?

When working with AngularJS services, TypeScript often recommends that I switch my code to use async/await functions. https://i.sstatic.net/vks1i.png While I understand that using the await keyword is compatible with third-party promises because it essen ...

Tips for displaying personalized data with MUI DatePicker

I need to create a React TypeScript component that displays a MUI DatePicker. When a new date is selected, I want a custom component (called <Badge>) to appear in the value field. Previously, I was able to achieve this with MUI Select: return ( ...

What is the best way to relocate the styles folder to the src folder while using nextjs, typescript, and tailwind

I am currently working with Next.js using TypeScript and Tailwind CSS. My goal is to relocate the styles folder into the src folder. I have already updated the baseUrl in my tsconfig.json file to point to the src directory, but I encountered the following ...

What methods are typically used for testing functions that return HTTP observables?

My TypeScript project needs to be deployed as a JS NPM package, and it includes http requests using rxjs ajax functions. I now want to write tests for these methods. One of the methods in question looks like this (simplified!): getAllUsers(): Observable& ...

Initial request in the sequence is a conditional request

Currently, I am attempting to make a request in rxjs that is conditional based on whether or not the user has uploaded a file. If a file has been uploaded, I need to attach it to the user object before sending it off, and then proceed to patch the user aft ...

"Implementing an Angular unit test for a method that calls a service

**I am trying to test the following method using Jasmine & Karma. The requirement is to cover all lines of code. However, I am struggling to achieve full code coverage. Any suggestions on how to approach this?** I attempted calling the method directly, bu ...

Place a new button at the bottom of the react-bootstrap-typeahead dropdown menu for additional functionality

Currently, I have successfully implemented the React Bootstrap Typeahead with the desired options which is a good start. Now, my next challenge is to integrate a custom button at the end of the dropdown list for performing a specific action that is not ne ...

Is there a method to incorporate absolute paths in SCSS while working with Vite?

Currently, I am experimenting with React + Vite as webpack seems to be sluggish for me. My goal is to create a project starter, but I am facing difficulties in getting SCSS files to use absolute paths. Despite including vite-tsconfig-paths in my vite.confi ...