Ionic 5 App on native devices Android + IOS is not Refreshing Data From REST API Instantly

I am creating an app using ionic 5 + angular 8, i am facing issue regarding data refreshing on the android and iOS devices, the issue is when i change the data on website its not reflecting instantly on the APP, i am consuming the wordpress REST API for this purpose, below is the ionic service code.

import { Injectable } from ‘@angular/core’;

import { HttpClient } from ‘@angular/common/http’;

import { Observable } from ‘rxjs’;

import { map } from ‘rxjs/operators’;

import { environment } from ‘src/environments/environment’;

@Injectable({

providedIn: ‘root’

})

export class ChurchService {

totalPosts = null;

pages: any;

constructor(private http: HttpClient) { }

getAnnouncements(page = 1): Observable<any> {

let options = {

  observe: "response" as 'body',

  params: {

    per_page: '10',

    page: '' + page

  }

};

return this.http.get<any[]>(`${environment.apiUrl}wp/v2/ncm-announcement?_embed`, options).pipe(

  map(resp => {

    this.pages = resp['headers'].get('x-wp-totalpages');

    this.totalPosts = resp['headers'].get('x-wp-total');

    let data = resp['body'];

    for (let announcement of data) {

      if (announcement['featured_media'] != 0) {

        announcement.media_url = announcement['_embedded']['wp:featuredmedia'][0]['media_details'].sizes['full'].source_url;

      } else {

        announcement.media_url = 'assets/no-image.png';

      }

    }

    return data;

  })

)

}
}

Your requirement is real time update that’s why you will have to use the Firebase.

Thanks!

@tripurarisingh, thanks for your reply, i am not really looking for real time updates but within a mint ionic sholud reflect the changes on the app, this is my problem can please provide any solution of this?

BTW i am using the WordPress REST API.

Thanks

I’m going to assume “mint” is intended to be “minute”.

If you’re being completely literal here, and 60 seconds is the maximum desired lag between updates, then you would need to poll the server at least that frequently.

That’s not typically a great strategy, because it wastes resources like battery life and bandwidth. This is why push notifications were invented, and that’s what I would recommend looking into as a more sustainable solution.

1 Like

Thanks & Sorry for the bad English

@rapropos actually the issue is when i am refreshing the records/results using ion-refresh still its showing old data i think after ion-refresh it should refresh the latest data? Because then i am requesting the server to refresh it. Can you please help me in this ?

Let me know if you want to further clarifications?

I don’t see anything you’ve posted so far involving <ion-refresh>. People trying to help need to have enough code to reproduce your problem.

Please find the code below

// Announcements page function for refresh the announcements

refreshAnnouncements(ev: any) { 
  this.wp.getAnnouncements().subscribe(res => {
      this.count = this.wp.totalPosts;
      this.announcements = res;  
      this.filterAnnouncements = this.announcements; 
      this.changeDetectorRef.detectChanges();
      ev.target.complete(); 
    }, (error) => { 
      if(error.status==404){
        this.presentToast('No News found!!');
      }else{
        this.presentToast('Error!! There is an error while getting the Data, Please Try again later.'); 
      }
      ev.target.complete(); 
    });
  }

// HTML code

<ion-refresher threshold="100px" slot="fixed" (ionRefresh)="refreshAnnouncements($event)">
    <ion-refresher-content></ion-refresher-content>
</ion-refresher>

// Service

getAnnouncements(page = 1): Observable<any[]> {

    let options = {

      observe: "response" as 'body',

      params: {

        per_page: '10',

        page: '' + page

      }

    };

    return this.http.get<any[]>(`${environment.apiUrl}wp/v2/ncm-announcement?_embed`, options).pipe(

      map(resp => {

        this.pages = resp['headers'].get('x-wp-totalpages');

        this.totalPosts = resp['headers'].get('x-wp-total');

        let data = resp['body'];

        for (let announcement of data) {

          if (announcement['featured_media'] != 0) {

            announcement.media_url = announcement['_embedded']['wp:featuredmedia'][0]['media_details'].sizes['full'].source_url;

          } else {

            announcement.media_url = 'assets/no-image.png';

          }

        }

        return data;

      })

    )

  }

I make it a rule to never modify external state in RxJS pipelines, with the sole exception of tap, which exists largely to facilitate that sort of thing (and even then, I try to do that as little as is humanly possible).

So I would eliminate all assignments to this.* inside that map block. map is for transforming an A into a B, and that’s all it should be doing. You need to define B such that it conveys everything you want to pass along to the next stage of the pipeline (and the eventual subscriber(s)).

What’s the value of environment.apiUrl?

1 Like

Thanks for your reply please see the ebvironment.apiUrl.

environment.apiUrl: https://ncmdev.com/church/wp-json/

Let me know if you need anything else to test it?

OK, it’s HTTPS, that’s good. Can you post the HTML in the template responsible for displaying the announcements (the part that doesn’t get properly updated on refresh)?

<ion-header>

  <ion-toolbar>

    <ion-buttons slot="end">  

      <ion-button (click)="searchBox=!searchBox" *ngIf="!searchBox">

        <ion-icon slot="icon-only" name="search"></ion-icon>

      </ion-button>

      <ion-button (click)="searchBox=!searchBox" *ngIf="searchBox">

        <ion-icon slot="icon-only" name="close"></ion-icon>

      </ion-button>

    </ion-buttons> 

    <ion-title class="ion-text-left">News</ion-title> 

  </ion-toolbar> 

  <ion-searchbar *ngIf="searchBox" [(ngModel)]="searchTerm" animated="true" showCancelButton="focus" debounce="500" (ionInput)="searchAnnouncements($event)"></ion-searchbar>

</ion-header> 

<ion-content>

  <ion-refresher threshold="100px" slot="fixed" (ionRefresh)="refreshAnnouncements($event)">

    <ion-refresher-content></ion-refresher-content>

  </ion-refresher>

  <ion-grid>

    <ion-row>

      <ion-col size="12" size-md="6" size-lg="4" (click)="openAnnouncementDetail(announcement.id)" *ngFor="let announcement of filterAnnouncements">

        <div class="event-card-single">

          <ion-card>  

            <ion-img [src]="announcement.media_url"></ion-img> 

            <ion-card-header> 

                <ion-card-title text-wrap [innerHTML]="announcement.title.rendered"></ion-card-title>  

            </ion-card-header> 

            <ion-card-content [innerHTML]="announcement.content.rendered.substring(0, 150) + '...'"></ion-card-content>

            <div class="readMoreLink">

              <span class="homeReadmore">Read More</span>

            </div> 

          </ion-card>

        </div>

      </ion-col> 

    </ion-row>

  </ion-grid>

  <ion-infinite-scroll threshold="100px" (ionInfinite)="loadMoreAnnouncements($event)">

    <ion-infinite-scroll-content loadingText="Loading more...">

    </ion-infinite-scroll-content>

  </ion-infinite-scroll>

</ion-content>

I didn’t notice this before, but this is really weird. Why is it here at all, and why is it pretending that one string is a different string?

In any event, is there a difference between refreshAnnouncements() and loadMoreAnnouncements()? If I just have one call the other, everything seems to work as I would expect it to.