Skip to content
Advertisement

Angular doesn’t update view on array push

I have an issue with a function which loads posts with the ionic infinite scroll component. The function works great on other components but in this one, the view doesn’t update when I push new posts into the array.

This is the function that doesn’t work:

 // handles infinite scroll
  // loads more posts when getting to the bottom of the page
  async loadMorePosts(event): Promise<void> {

    await this.postService.getUserPosts(this.userId, this.offset).toPromise().then((posts: Posts) => {
      posts.rows.forEach((post: Post) => {
        this.posts.push(post)
      })
    })

    event.target.complete()
    // increments offset for the next query
    this.offset += this.offset

    //  if all data is loaded, disables infinite scroll
    if (this.posts.length == this.totalPosts) {
      event.target.disabled = true;
    }
  }

This is the one that works:

 // handles infinite scroll
  // loads more posts when getting to the bottom of the page
  async loadMorePosts(event): Promise<void> {

    await this.postService.getOwnPosts(this.offset).toPromise().then((posts: Posts) => {
      return posts.rows.forEach((post: Post) => {
        this.posts.rows.push(post)
      })
    })
    
    event.target.complete()
    // increments offset for the next query
    this.offset += this.posts.offset

    //  if all data is loaded, disables infinite scroll
    if (this.posts.rows.length == this.totalPosts) {
      event.target.disabled = true;
    }
  }

Here is the html:

<ion-content>
  <ion-refresher slot="fixed" (ionRefresh)="doRefresh($event)">
    <ion-refresher-content></ion-refresher-content>
  </ion-refresher>
  <ion-grid id="profile" class="ion-no-padding">
    <ion-row class="ion-justify-content-center">
      <ion-col class="profile" size="10">
        <div>
          <ion-avatar class="profile__avatar">
            <ion-img src="/assets/img/profile_img.jpeg"></ion-img>
          </ion-avatar>
        </div>
        <div class="profile__gym">
          <div class="profile__gym-location">
            <ion-icon name="location-sharp"></ion-icon>
            <p>{{profile?.gym}}</p>
          </div>
          <div class="profile__gym-sport">
            <ion-img src="/assets//img/male_flexin.png"></ion-img>
            <p>{{profile?.discipline}}</p>
          </div>

        </div>
      </ion-col>
    </ion-row>

    <ion-row class="ion-justify-content-center">
      <ion-col size="9">
        <div class="description">
          <p>{{profile?.bio}}</p>
        </div>
      </ion-col>
    </ion-row>

    <ion-row class="ion-justify-content-evenly buttons">
      <ion-col size="4">
        <ion-button (click)="follow()" mode="ios" expand="block">
          {{profile?.isFollowing ? "Abonné(e)" : "S'abonner" }}
        </ion-button>
      </ion-col>
      <ion-col size="4">
        <ion-button (click)="navigateToDirectMessages()" mode="ios" expand="block">
          Écrire
        </ion-button>
      </ion-col>
    </ion-row>

    <ion-row class="ion-justify-content-center">
      <ion-col size="10">

        <div (click)="navigateToFollowers(profile?.user_id)" class="follow-count">
          <div class="follow-count--flex-column txt-center">
            <p>{{totalPosts}}</p>
            <p class="follow-count__txt">Posts</p>
          </div>
          <div class="follow-count--flex-column txt-center">
            <p>{{following?.count}}</p>
            <p class="follow-count__txt">Abonnements</p>
          </div>
          <div class="follow-count--flex-column txt-center">
            <p>{{followers?.count}}</p>
            <p class="follow-count__txt">Abonnés</p>
          </div>
        </div>

      </ion-col>
    </ion-row>

    <ion-row class="ion-justify-content-center ion-margin-bottom">
      <ion-col size="10">

        <div class="sections">
          <div (click)="setSection(0)" class="sections__gallery">
            <p>Gallerie</p>
            <ion-icon *ngIf="indexSection == 0" name="ellipse"></ion-icon>
          </div>

          <div (click)="setSection(1)" class="sections__routine">
            <p>Programmes</p>
            <ion-icon *ngIf="indexSection == 1" name="ellipse"></ion-icon>
          </div>

          <div (click)="setSection(2)" class="sections__nutrition">
            <p>Diète</p>
            <ion-icon *ngIf="indexSection == 2" name="ellipse"></ion-icon>
          </div>
        </div>

      </ion-col>
    </ion-row>

    <ion-row class="card-row">
      <ion-col>
        <ion-card class="card">
          <ion-slides [options]="sliderOpts" #slides (ionSlideDidChange)="slideToSection()">
            <ion-slide>
              <div class="gallery">
                <div class="gallery__img" *ngFor="let post of posts ; let i = index">
                  <ion-img (click)="openLightbox(i)" [src]="imgUrl+post?.img"></ion-img>
                </div>
                <div *ngIf="!posts" class="gallery__placeholder">
                  <ion-label>Cette section est vide</ion-label>
                </div>

              </div>
            </ion-slide>

            <ion-slide>
              <div class="program">
                <ion-card *ngFor="let program of profile?.programs ; let i = index">
                  <ion-item (click)="navigateToProgram(program?.id)" detail lines="none">
                    <ion-label>
                      <h5>
                        {{setDay(program?.day)}}
                      </h5>
                    </ion-label>
                  </ion-item>
                  <ion-item lines="none">
                    <ion-icon slot="start" size="small" name="time-outline"></ion-icon>
                    <ion-label>
                      {{program?.duration}}</ion-label>
                  </ion-item>
                </ion-card>
                <div *ngIf="profile?.programs?.length == 0" class="program__placeholder">
                  <ion-label>Cette section est vide</ion-label>
                </div>
              </div>

            </ion-slide>

            <ion-slide>
              <div class="nutrition">
                <ion-card (click)="navigateToMeal(meal?.id)" *ngFor="let meal of profile?.meals">
                  <ion-item class="nutrition__meal" detail lines="none">
                    <ion-label>
                      <h3>
                        {{meal?.name}}
                      </h3>
                      <p>{{meal?.time}}</p>
                    </ion-label>
                    <ion-label class="nutrition__meal-cal">
                      <h3>{{calculateTotalNutriments(meal?.meal_components,"kcal_100g") | number:'1.1-1'}}Kcal</h3>
                    </ion-label>
                  </ion-item>
                  <ion-item lines="none" class="nutrition__meal-macros">

                    <ion-icon class="proteins-ellipse" name="ellipse"></ion-icon>
                    <ion-label>
                      <h5>Protéines</h5>
                      <p>{{calculateTotalNutriments(meal?.meal_components,"proteins_100g") | number:'1.1-1'}}g</p>
                    </ion-label>

                    <ion-icon class="carbs-ellipse" name="ellipse"></ion-icon>
                    <ion-label>
                      <h5>Glucides</h5>
                      <p>{{calculateTotalNutriments(meal?.meal_components,"carbohydrates_100g") | number:'1.1-1'}}g</p>
                    </ion-label>
                    <ion-icon class="fat-ellipse" name="ellipse"></ion-icon>

                    <ion-label>
                      <h5>Lipides</h5>
                      <p>{{calculateTotalNutriments(meal?.meal_components,"fat_100g") | number:'1.1-1'}}g</p>
                    </ion-label>

                  </ion-item>
                </ion-card>
                <div *ngIf="profile?.meals?.length == 0" class="nutrition__placeholder">
                  <ion-label>Cette section est vide</ion-label>
                </div>
              </div>

            </ion-slide>

          </ion-slides>
        </ion-card>
      </ion-col>
    </ion-row>

  </ion-grid>

  <app-lightbox id="lightbox" class="lightbox" [totalPosts]="totalPosts" [postIndex]="postIndex" [posts]="posts">
  </app-lightbox>
  <ion-infinite-scroll (ionInfinite)="loadMorePosts($event)">
    <ion-infinite-scroll-content loadingSpinner="crescent">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>

I’m new to this so if some informations are lacking or my request isn’t properly formed, please feel free to say so.

Thanks for the help

Advertisement

Answer

My problem has been solved. There were conflicts with the card margin and overflow when the change detection was triggered, the new post was hidden underneath.

Advertisement