Execute a function only once every time i run my app

Hello, im developing an app for android (and maybe for ios in the near future), and i cant find a way to do something…

I need to check if some information is available from a REST api every time the user starts the app. So far i’ve tryed this:

in app.component.ts

constructor(private platform: Platform) {
    initializeApp();
}

initializeApp() {
    this.platform.ready().then(() => {
      this.diarios.initializeDiarios(); // this checks if there's new info to download
    }
  }

The problem is that this approach makes my method fire every time i load a new page (when i navigate through my app, this function fires every time i go to another page), not only at start as i need. The idea is to check if there’s new info in my service, if true, then update some stuff, if false, then don’t check until the next time the user opens the App.

Any ideas on how to do it? or what am i doing wrong?

I don’t understand why things are happening the way you describe, but in any event, I would do this in the constructor of a service provider, not the app component.

i was following a guide on internet on how to add a service and it was like that, im new to angular-ionic so probably im making a lot of mistakes!

I’ll try to move my code to the service constructor and see if that makes any difference.

By the way, why wouldn’t you do it on the app component?

Because I like to separate responsibilities heuristically. It helps me find code faster, it helps me locate bugs, and it makes stuff more testable, self-documenting, and extensible.

So I consider components the “face” of an app. They present and acquire business-layer objects from the user. Services, on the other hand, are responsible for managing business-layer objects - marshalling and unmarshalling them, storing them, caching them, making network backend requests to save and fetch them.

So I forbid direct HTTP or storage access in my components, and the activity you seem to be describing here I would consider a service provider job.

Yeah that makes a lot of sense actually.

But then, is it ok if i create an instance of my service on the app.component constructor like

constructor (private diarios: ApiDiarios)

and then in the service constructor i fire the function? or how should i do then to start my service when the app starts?

Sure, but chances are some other page will need to inject ApiDiarios, so you probably won’t have to do it in the app component.

All things considered, “every time the app is launched” is a decent, reasonable choice for a periodic task like this. However, if you want to get a little more elaborate, you could use Ionic Storage to store the last time you made this check. This would let you set a policy like “check at most once every 4 hours”, and on each launch, instead of blindly issuing the request, you could do nothing in the case where the last check was made within that 4 hour window.

Yes that is something i also thought of, and I’m doing that, actually I check every hour like this:

if ((this.now - this.lastCheck) > 3600000 ) { // 'now' is the actual time in MS, 'lastCheck' is the last time the function fired
            console.log("chequeando si hay diarios nuevosss");
            this.initializeDiarios();
          }

And if initializeDiarios() fires, then it does this:

this.storage.set('lastCheck', (new Date().getTime()))
.then( () => { 
           console.log("lastCheck set");
});

However, because of the nature of the app (it downloads newspaper pages), i need to check every time the app starts in case there’s something new to download, despite if it has been an hour since the last time it checked or not. After that first check, then its ok to check again every hour…

Does that make sense?

edit: I just tested firing from the service constructor and its the same result, it fires every time i navigate to a new page

Something is seriously broken here. Can you make a publicly accessible repo on gitlab or github that reproduces the situation?

I will try, i’ve never used github before, so it may take a while until i learn how to (im literally reading the guide now)…

I’ve tryed with a fresh new app, from scratch, and it behaves exactly the same. If it helps, here is my ionic info:

Ionic:

Ionic CLI : 6.10.1 (C:\Users\agusd\AppData\Roaming\npm\node_modules@ionic\cli)
Ionic Framework : @ionic/angular 5.3.1
@angular-devkit/build-angular : 0.901.12
@angular-devkit/schematics : 9.1.12
@angular/cli : 9.1.12
@ionic/angular-toolkit : 2.3.0

Capacitor:

Capacitor CLI : 2.4.0
@capacitor/core : 2.4.0

Cordova:

Cordova CLI : 9.0.0 (cordova-lib@9.0.1)
Cordova Platforms : android 8.1.0
Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.2.1, (and 7 other plugins)

Utility:

cordova-res : not installed
native-run : 1.0.0

System:

Android SDK Tools : 26.1.1 (C:\Users\agusd\AppData\Local\Android\Sdk)
NodeJS : v12.18.2 (D:\Program files\Node\node.exe)
npm : 6.14.5
OS : Windows 10

And im testing in an android 5.0 device

If I can provide any other info just ask me