Asynchronous data changes aren't rendered


I’m building a Twitter client for Android and facing problems when liking tweets, more precisely when updating the data. So the user clicks on the heart icon and triggers this function:

like(id) {
  this.twitter.likeTweet(id).then(() => {["favorited"] = true;["favorite_count"]++;

The favorite_count is displayed next to the heart icon. After successfully executing the function (tweet is liked, data is changed) the component doesn’t get rendered again. The then part is definitely executed.
Changing to async/await doesn’t solve the problem. So what I assume is, that changing data in an asynchronous context doesn’t work. Can anyone point out why this is the case and how it can be solved?

I have to mention that the data is passed as an input to the component. Could this be a problem? Since this couldn’t be avoided, I hope not.

If I don’t wait for the twitter.likeTweet response, it’s working fine:

like(id) {
  this.twitter.likeTweet(id);["favorited"] = true;["favorite_count"]++;

So changing the data and see the changes directly in the rendered component works in principal. But I prefer the way using a promise to know that the communication with the Twitter API was successful.

This is the first time I’m posting in this forum, so if anything is missing or wrong, please let me know. Thanks in advance.

Please describe how this.twitter is initialized.

So is the issue in the html template not being updated while you confirm the data was updated? or the data is not getting updated?

Basically you need to understand if this is change detection issue or there is something that prevents your data from being updated.

Now also think about your second example - it is called optimistic updates. I think that approach is generally better from UX perspective (you set likes locally and await response from service, if that’s positive - all good, if errors - then you revert the data change). But I guess it depends on what twitter service is.

It gets injected by the constructor. For better understanding, here is the full code of this component:

import { Component, Input } from "@angular/core";
import { TwitterApiProvider } from "../../providers/twitter-api/twitter-api";

  selector: "tweet-actions",
  templateUrl: "tweet-actions.html"

export class TweetActionsComponent {
  data: any[];

  constructor(private twitter: TwitterApiProvider) {}

  like(id) {
    this.twitter.likeTweet(id).then(() => {["favorited"] = true;["favorite_count"]++;

  removeLike(id) {
    this.twitter.unlikeTweet(id).then(() => {["favorited"] = false;["favorite_count"]--;

A potential cause here is zone mismatch, which is generally something you shouldn’t need to be worrying about, and is a large reason why the entire ionic-native project exists.

If whatever is behind TwitterApiProvider is Angular-aware (I don’t know the exact names of Angular Twitter libraries, but I assume there are several), then you should be OK.

If it isn’t Angular-aware, probably the easiest thing to do is to swap it out for something that is. Another alternative workaround would be to wrap whatever Promise you are getting from non-Angular-aware-library inside Promise.resolve(). That results in a zone-aware Promise that will behave as you would expect. You could achieve the same effect with manually running change detection or, but those are definitely uglier and less sustainable roads to travel.


The TwitterApiProvider uses twit which seems not to be Angular-aware. Since this is my first project with Angular and Ionic, I wasn’t aware of this zone problems. Thanks for pointing it out.

Finally, I solved it running change detection manually. As you already mentioned, this is a bit ugly. But I didn’t manage to get it running with Promise.resolve(). Maybe you can share an example how you planned to use it? :slight_smile:
The function in the provider looks like this:

public async likeTweet(tweetId) {
  return await"favorites/create", { id: tweetId });

Anyway, thank you very much @rapropos! And also thank you @cmer4 :slight_smile:

I am not a big fan of async/await, largely because of situations like this. It obscures what is really going on.

I ran into something similar with WebCrypto. Basically everywhere you get one of these external Promises, you wrap it before it gets out:

likeTweet(tweetId: string): Promise<void> {
  return"favorites/create", { id: tweetId });


likeTweet(tweetId: string): Promise<void> {
  return Promise.resolve("favorites/create", { id: tweetId }));

Anything outside of TwitterApiProvider can then be blissfully unaware of any of this.

Thank you for the example! Unfortunately, this doesn’t work :confused:

If this project is still in the early stages, you might want to think about divorcing yourself from that twit library. It looks rather crufty. Twitter has decent docs for their REST API, and Angular’s HttpClient will give you much more advanced fundamental functionality than twit can.

The Tour of Heroes part 6 covers using HttpClient, and if you’re new to Angular in general, going through the whole thing might save you a lot of bashing-head-into-wall as you work on this.