Using trackBy in conjunction with the async pipe

Attempting to utilize the async pipe along with *ngFor to exhibit an array of items obtained asynchronously.

<ul>
  <li *ngFor="let item of items | async; trackBy: trackPost">
    {{item.text}}
  </li>
</ul>

ngOnInit() {
  // a simple http call that fetches an array of [{id: 1, text: "something"}]
  this.items = this.itemService.loadItems();
}
trackPost(index, item) { return item.id; }

The process works smoothly. However, when I attempt to include an additional item:

async addItem(text) {
  await this.itemService.addItem({text});
  // reload items after adding
  this.items = this.itemService.loadItems();
}

This method is effective and updates the items correctly post addition.

The dilemma arises as it refreshes the entire array instead of just appending items. This becomes evident through animations (if there are any). While I understand that managing the subscription manually and working with arrays can solve this issue, I am curious if there's a way to address this using the async pipe.

Is there a means for me to add the new item onto the existing observable? If not, is there a way to ensure the template accurately tracks the items instead of treating them as newly added?

Answer №1

The issue arises when you reassign the stream using

this.items = this.itemService.loadItems();
. This means that your Observable items does not emit new values for Angular to track with your trackBy function. Instead of changing the reference of items, causing Angular to do a full reload, update your addItem function in your service to emit the updated values to the existing Observable retrieved via loadItems. Here's how you can do it:

addItem(text) {
  this.itemService.addItem({text});
}

Here's an example of a service implementation following this approach:

@Injectable()
export class Service {
    private items: Array<string> = [];
    private items$ = new Subject<Array<string>>();

    loadItems(): Observable<Array<string>>  {
        return this.items$.asObservable();
    }

    addItem(text: string) {
        this.items = [...this.items, text];
        this.items$.next(this.items);
    }
}

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

utilize TypeScript to iterate through an array in a JSON object

How can I loop through the subjects array in a JSON response? JSON Response: { "$id": "1", "Council_ID": 116, "number": "67", "subjects": [ { "$id": "2", "subjectCode": "67", "type": 4, ...

Utilizing Nginx to Reverse Proxy to Node.js and Implement Rewrites

I have various applications running in the background behind an Nginx reverse proxy. One of these applications is a Node server using Express.js. I am forwarding domain.com/demo/app/<path> to localhost:7003/<path> through this Nginx configurati ...

Utilize Twilio to forward messages to a different phone number

I am seeking a solution to automatically forward incoming messages from one Twilio number to another, based on the original sender's number. For example: If I receive a message on my Twilio number "+14444444444" from '+15555555555', I want ...

Text generated dynamically for buttons

I need help with updating the text on dynamically generated buttons. I tried a method below, but it's not working. $(document).on('click', '.class', function(e){ var thisbut = this.id; $.post('my.php',{ val: val1 ...

Triggering jQuery accordion when clicked

I have a challenge to tackle - I want to create an accordion system that can display and hide quotes at various points on the page. My desired outcome is to have one quote displayed per accordion panel. When I expand an accordion, I want to show the cont ...

I'm encountering an issue where Typescript is unable to locate the Firebase package that I

I have a TypeScript project that consists of multiple .ts files which need to be compiled into .js files for use in other projects. One of the files requires the firebase package but it's not being found. The package is installed and located inside t ...

Executing a Shortcode Using a Button in Visual Composer for Wordpress

It should be easy to do this. I've got a great plugin with a modal newsletter signup form that offers various launch options, including manual launching with the following codes. https://i.stack.imgur.com/IGbsp.png My theme utilizes Visual Composer. ...

An error was encountered in compiler.js at line 1021, stating that an unexpected value 'UserService' was imported by the module 'UserModule'. It is recommended to add a @NgModule annotation to resolve this issue

As a PHP programmer new to Angular, I am facing an issue while trying to retrieve user properties from a Laravel API. When attempting this, I encountered the following error: compiler.js:1021 Uncaught Error: Unexpected value 'UserService' importe ...

Utilizing SPServices and jQuery for seamless CORS functionality

Trying to access a SharePoint list from a different domain on a mobile device. Below is the code snippet for a simple get request: $.support.cors = true; $(function() { $().SPServices({ operation: "GetListItems", webURL: "http://myurl.com/project ...

How can I retrieve the value of a JavaScript variable using Ajax?

Hello everyone! I've been a long-time user of various programming forums, but this is my first time posting. Lately, I created a really simple browser-based game, and when I say simple, I mean it's incredibly basic. The whole game logic resides ...

Looking to show an image when a checkbox is ticked and hide it when it is unticked in HTML?

How do I make a specific image appear when a user clicks on a checkbox? I'm unsure if I should use jQuery, Ajax, or another method. What is the best approach for this task? Your assistance would be greatly appreciated. I have successfully created the ...

AngularJS - Click event failing to trigger controller function

I am currently honing my skills in Angularjs and Nodejs through working on a project. Following a helpful tutorial, I have structured my folders and configured my routes. Issue: I implemented a method called isActive to update ng-class when a tab is ...

What makes this code run synchronously?

function foo(cb) { if (!someAuditCondition) { return cb(new Error(...)); // <- Despite this part being synchronous, the rest of the function is asynchronous. } doSomeAsynAction(function (err, data) { if (err) { return cb(err); } cb( ...

Discover the root cause of why an element is being prioritized

Is it possible to determine what is causing the first html element (input, textarea) to gain focus? While loading a modal window, I am unable to locate the line of JavaScript that is setting focus() on this initial element. One workaround is to blur() it ...

Encountered an Unexpected Token SyntaxError in Node.js

When setting up the routers for the API, I have defined them for both POST and GET requests like this: var bookRouter = express.Router(); bookRouter.route('/Books') .post(function(req, res) { var bok = new book(req.body); con ...

The data in the Angular 12 data table remains hidden until the modal is activated

Whenever I don't include this.getEmployee(1); in my menu.component.ts within the ngOnInit() function, the table appears empty until I click the edit button. It's strange how all the information suddenly shows up on the table. I'm trying to a ...

Guide to sending a HTTP POST request with parameters in typescript

I need assistance sending a POST request using parameters in the following format: http://127.0.0.1:9000/api?command={"command":"value","params":{"key":"value","key":"value","key":"value","key":value,}} I attempted to do this but encountered an issue: l ...

jqGrid and the use of prototype functions

When using prototype functions in my code, I encounter an issue where adding a select box to the jqgrid results in an extra option being added at the bottom with a value that is a function. However, when I remove the prototype functions, everything works a ...

Different ways to prevent invalid entries in an input field with type datetime-local

<input type="datetime-local" step="1"> Is there a way to prevent invalid date input? For example, entering a date like "11:11:1111" in the format "mm-dd-yyyy". How can this be addressed using Moment.js? ...

Tips for customizing the color of mat-select placeholder text?

I've been attempting to modify the color of a mat-select placeholder. It functions properly when using 'background-color' but not when using 'color'. Below is my CSS code: /deep/ .mat-select-placeholder { color: red; } .mat-s ...