Include new item to the Observable array in TypeScript

I've created an Angular 2 component that utilizes a service to fetch data from a REST API.

import { OnInit, Component } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service2';
import { Observable } from 'rxjs';


@Component({
    selector: 'my-list',
    templateUrl: 'app/hero-list.component.html',
})
export class HeroListComponent implements OnInit {
  errorMessage: string;
  heroes: Observable<Hero[]>;
  mode = 'Observable';

  constructor (
      private heroService: HeroService
  ) {}

  ngOnInit() { this.getHeroes(); }

  getHeroes() {
    this.heroes = this.heroService.getHeroes()
  }

  addHero (name: string) {
    if (!name) { return; }

    this.heroService.addHero(name)
                     .subscribe(
                       hero  => this.getHeroes()
                     );
  }
}

Is there a more efficient way to improve the addHero function? Currently, it seems inefficient. I want to simply add the returned hero from this.heroService.addHero() to the heroes observable. How can I achieve this?

Answer №1

It is unnecessary to assign the Observable returned by heroService.getHeroes() to the heroes property and then reassign it each time a new Hero is added.

To enhance the HeroListComponent without modifying HeroService, you can do the following:

heroes: Hero[];

  ngOnInit() {
    this.getHeroes();
  }

  getHeroes() {
    this.heroService.getHeroes().subscribe(heroArray => {
      //Assign the array of Hero directly to the heroes property
      this.heroes = heroArray;
    });
  }

  addHero (name: string) {
    //Ensure that name is not an empty string. Any other errors will be caught by the Typescript compiler.
    if (name) {
      this.heroService.addHero(name).subscribe(hero => {
        //Assuming the response from adding a Hero is a Hero object
        this.heroes.push(hero);
      });
    } else {
      //Log an error message to console if an empty string is passed
      console.error('Error! addHero was passed an empty string!');
    }
  }

You may consider additional improvements by adjusting your HeroService, but this approach is a good starting point.

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

Typescript: Select just one option from the union

There is a specific Query type that contains the getBankAccounts property: export type Query = { getBankAccounts: GetBankAccountsResponseOrUserInputRequest, }; This property can return either a GetAccountsResponse or a UserInputRequest: export type Ge ...

Can you give me some insights about what an Action Creator is?

function createRefDoneAction(widgetsArray: widget[]): WidgetAction { return { type: actionTypes.REFRESH_WIDGET_DONE, widgets: widgetsArray }; } Could you please clarify the necessity of having two sets of parameters (e.g. 'wid ...

Is your Typescript compilation running into a problem with jwt tokens?

Having issues while trying to compile a typescript file as the compiler is throwing an error message: Error: TS2339 - The property 'payload' does not exist on type 'string | object'. Property 'payload' does not exist on type ...

Why is it necessary to redefine the interface and its class in Typescript after initially defining the interface with implements?

interface Filter { rowAddRow: (treeData:Tree[],id:string,filterType:FilterType) =>Tree[] } class FilterAction implements Filter { // I must redeclare here to ensure the correct type for id rowAddRow(treeData:Tree[], id, filterType):Tree[] { ...

Guide to adjusting column width in an XLSX worksheet using Angular4

I am trying to convert HTML into an XLSX sheet in Angular using SheetJS. However, I am encountering an issue where the width of each column is limited to 256 only, and I need to increase it. I have attempted to use ws[!cols] of ColInfo, but I am strugglin ...

What is the best way to utilize the features of component A within component B when they exist as separate entities

Component A has all the necessary functionalities, and I want to use it in Component B. The code for ComponentA.ts is extensive, but it's not written in a service. How can I utilize the logic from Component A without using a service, considering both ...

When it comes to passing prop values through functions, TypeScript types do not provide suggestions

I'm struggling to find a way to ensure that developers have suggested types for specific props in my component, regardless of how they pass data to the prop. For example, when I directly pass an array of values to the prop: <Component someProp={[{ ...

Encountering the issue: "Property '...' is not found on the type 'typeof "...."'"

Currently, I am in the process of developing a node js application using typescript. To transpile the code, I am utilizing the gulp transpiler in commonjs mode. One of the files I've written is homeController.ts, which looks like this: let homeContr ...

Enum-centric type guard

Could I create a custom type guard to verify if a specified string is part of a specific string enum in a more specialized way? Check out the following example: enum MyEnum { Option1 = 'option one', Option2 = 'option two', } const ...

Ways to make a component gradually appear and disappear in an Angular application

I have developed a task management application using Angular and I wanted to implement a fading effect for each task when it is created and before it is deleted. Despite successfully applying the fade in effect at the todo-item component level, I encounter ...

Essential front-end tools for enhancing Angular 2 projects

Hi there! I specialize in Laravel development and am currently diving into the world of Angular 2 framework. Up until now, I've been handling my third-party front end assets through bower, using a bower.json file to manage dependencies. Check out a sn ...

Issue with Angular 6 Snap-to-Component Directive's Functionality in Chrome Browser

I have developed a Snap-to-Component Directive that functions perfectly in Firefox but encounters issues in Chrome. I have checked canIUse and it should be compatible, so I am seeking insights, especially regarding cross-browser compatibility. Your input i ...

Tips for executing embedded scripts within templates

I am using a controller to display the Instagram embedded code <div class="instagram_here" [innerHtml]="instagram_embeded_code"></div> However, it is only showing a blank Instagram block. https://i.stack.imgur.com/gNPDL.png I suspect there m ...

Best Practices for utilizing search feature in Angular version 13

Can someone please guide me on the correct way to implement search functionality? I want the results to be displayed in a separate component and prevent the user-entered value from being refreshed for further searches. https://i.sstatic.net/bPqUr.jpg Thi ...

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 ...

The 'import type' declaration cannot be parsed by the Babel parser

Whenever I attempt to utilize parser.parse("import type {Element} from 'react-devtools-shared/src/frontend/types';", {sourceType: "unambiguous"}); for parsing the statement, I come across an error stating Unexpected token, exp ...

Input for uncomplicated changing identifier

I am looking to create types for dynamic keys that will be of type number. I have two similar types defined as follows: type UseCalculatePayments = () => { totalPayments: number; aggregate: number; condition: boolean; }; type UseCalculateCommissio ...

JEST: Troubleshooting why a test case within a function is not receiving input from the constructor

When writing test cases wrapped inside a class, I encountered an issue where the URL value was not being initialized due to dependencies in the beforeAll/beforeEach block. This resulted in the failure of the test case execution as the URL value was not acc ...

In Ionic 4, a special character is showing up before the form tag

I'm facing a bizarre issue with my Ionic 4 app... a strange character is appearing before the form https://i.sstatic.net/Y7Txh.png I tried using Google DevTools, but I couldn't identify how this extra character is being injected before the form ...

Using cdk-virtual-scroll-viewport in combination with Angular and flex-layout (row and wrap)

I am interested in implementing virtual scrolling with flexlayout. For example, I would like the following code to be compatible with virtual scrolling: <div fxLayout="row wrap" fxLayoutAlign="start center"> <div *ngFor=&qu ...