Reset function after leaving the view


#1

Hi, I hope you’re well!

I have a view for a timeline. Every post has a click=() to push to the owner user profile of that post. It load the profile and its content, when you back to timeline and click on another user post, the view doesnt reaload the provider, so the profile is the same visited first.

Here’s the code:

feed.html:

<ion-card *ngFor="let post of feed;">
      <ion-item>
        ...
        <h2 (click)="onViewProfiles(post.owner.id)">{{post.owner.first_name}} {{post.owner.last_name}}</h2>
        ...
      </ion-item>
      ...
</ion-card>

feed.ts:

export class FeedPage {
  ...
  onViewProfiles(user_id: string) {
    this.navCtrl.push(ProfilesPage);
    window.localStorage.setItem('user_id', user_id);
  }

profile.ts:

export class ProfilesPage {
  ...  
  public profile: any;
  constructor(public profilesService: ProfilesService, 
                   public navCtrl: NavController,
                   public translate: TranslateService) {
    this.loadProfiles();
    window.localStorage.removeItem('user_id');
  }

  loadProfiles(){
    this.profilesService.load()
    .then(data => {
      this.profile = data;
    });
  }

Finaly provider.ts:

@Injectable()
export class ProfilesService {
  data: any;
  user_id: string;

  constructor(public http: Http) {
    this.user_id = window.localStorage.getItem('user_id');
  }

  load() {
  if (this.data) {
    return Promise.resolve(this.data);
  }

  return new Promise(resolve => {
    this.http.get(global.API_PROFILES + this.user_id + '/') 
      .map(res => res.json())
      .subscribe(data => {
        this.data = data;
  	resolve(this.data);
        this.user_id = null;
      });
    });
  }
}

remove Item, set user_id = null, none of these methods work, I think the problem is that the provider is not unloading and loading again. Is it something with the @injectable()?


#2

if you use the backbutton device to comeback to timeline you must add this code to your app.component.ts :
add
import { Platform } from 'ionic-angular';
add Platform to app.component.ts constructor

constructor(public platform: Platform)

in your app.component.ts constructor add this :

 platform.ready().then(() => {
            platform.registerBackButtonAction(() => {
               //init your user id or set code to refresh your timeline view
            });
        });

#3

I think the issue is that the view is cached (by default). Instead of clearing the user id in the constructor, use one of the Ionic lifecycle events instead. IonViewWillEnter should be the correct event to have the code rerun.


#4

Need a way to reload the provider, when I check the console the get request is trigger just once


#5

Ok, this solve the problem:

First remove the user_id from the localStorage, like this:

  onViewProfiles(user_id: string) {
    this.navCtrl.push(ProfilesPage);
    window.localStorage.removeItem("user_id");
    window.localStorage.setItem('user_id', user_id);
  }

Then chenge the provider to this:

@Injectable()
export class ProfilesService {
	data: any;
  user_id: string;

  constructor(public http: Http) {
  }

  load() {
  this.user_id = window.localStorage.getItem('user_id');
  return new Promise(resolve => {
    this.http.get(global.API_PROFILES + this.user_id + '/') 
      .map(res => res.json())
      .subscribe(data => {
        this.data = data;
  	resolve(this.data);
      });
    });
  }
}

#6

There are several things in the previous post which is considered the “solution” that I think could be improved on.

  • Instead of using window.localStorage to communicate across the app, just use the service provider
  • Always type everything. data should have a proper type (not any) and load() should be declared to return Promise<Profile>.
  • Give properties meaningful names. Avoid data, item, &c. In this case, it seems data should be profile.
  • Try to design in order to eliminate bug possibilities. Here we have no way of knowing whether the profile in ProfileService is reliable. If we do it this way instead, we do:
profile = new ReplaySubject<Profile>(1);

fetch(uid: string): void {
  this.http.get(url)
    .map(rsp => rsp.json())
    .subscribe((prof) => this.profile.next(prof));
}