1

I have a class for reloading some elements.

const getMe = async () => await 
  fetchURL("https://MY.SITE/api/users/me")
    .then((res) => res.data);

class loader {
  EVERYonceWHENmethodCALLED() {
    self.ME = (async () => await getMe())();
  }
  me() {
    $("#me").html(`${self.ME.grade}${self.ME.number}[Tickets: ${self.ME.likeTicket}]`);
  } // ** likeTicket depends on ME **
  async chart() {
    if ($("body").find("#chart").length) {
      const musicChart = await fetchURL(`https://MY.SITE/api/music/chart?&gender=${self.ME.gender}`);
      $("#chart").html(await listElementsOf(musicChart.data.list));
    } // ** listElementsOf depends on ME ( It lets me know what musics I 'liked' to ) **
  }
  async search(q) {
    if ($("body").find("#searchResult").length){
      if(q) $("#searchResult").attr("data-q", q);
      else q = $("#searchResult").attr("data-q");

      const searchResult = await fetchURL(`https://MY.SITE/api/music/search?q=${q}`);
      $("#searchResult").html(await listElementsOf(searchResult));
    }
  }
  meAndChart() {
    self.me();
    self.chart();
  }
  loadEverything() {
    self.meAndChart();
    self.search();
  }
}

I need to reload ME before reloading any other element, and I'm seeking a way to do this. I can employ new like new loader.me();, but I don't want to use new every time.

Is there any way for the intended job? Thanks for reading.

dbld
  • 998
  • 1
  • 7
  • 17
  • It's unclear to me what the *other elements* are (DOM elements?). And how would you reload them? Why do you want to reload `ME` if it is not even used in you class? I can't make much sense of your code. – GOTO 0 Apr 12 '22 at 07:55
  • @GOTO0 Actually other methods use ME, but for security(?) I covered it. `elements` are DOM elements as you said, and I need to use ME, private user detail, to reload 'me' and 'chart' elements. I reload them by re-fetching data from the target site. ex) `const musicChart = await fetchURL(\`https://MY.SITE/api/music/chart?gender=${self.ME.gender}\`;` `$("#chart").html(await listElementsOf(musicChart.data.list));` - I used JQuery. – dbld Apr 12 '22 at 08:13
  • I would put the `fetchURL` calls into a central function and use only that function to fetch data. Then, in that function, you could load `ME` only if necessary. – GOTO 0 Apr 12 '22 at 08:38
  • @GOTO0 I don't get what you mean by 'central function'. I edited my question so that you can understand the overall structure, so please let me know how to make it. Thanks – dbld Apr 12 '22 at 08:54
  • So, the methods in your code where `ME` is being referenced are `me` and `chart`, right? And you want to run `EVERYonceWHENmethodCALLED` before any of those two? – GOTO 0 Apr 12 '22 at 09:09
  • @GOTO0 You're right, but I don't want them to load ME double time when I called `loader.meAndChart()`. – dbld Apr 12 '22 at 09:12
  • 1
    Ah, I see. Well a typical approach would be creating internal methods for `me` and `chart` that run without reloading `ME`, and public methods that call `EVERYonceWHENmethodCALLED` before doing so. `meAndChar` would call `EVERYonceWHENmethodCALLED` first, and then the internal methods. – GOTO 0 Apr 12 '22 at 09:48
  • @GOTO0 Appreciate your tip. I will implement that way. – dbld Apr 12 '22 at 12:51
  • 1
    I've added an answer to show the code in detail. – GOTO 0 Apr 12 '22 at 13:41

1 Answers1

1

I made some changes to your code:

  • change EVERYonceWHENmethodCALLED so that ME is set to the awaited object rather than a promise.
  • Using this instead of self for the current object (see here for details).
  • Renamed me and chart to _me and _chart respectively.
  • Added methods me and chart that call the internal methods after EVERYonceWHENmethodCALLED.
  • Updated meAndChart to call the internal methods after EVERYonceWHENmethodCALLED.

Note that it is generally a good practice (and often necessary) to call async functions with await, and that requires the caller functions to be also async.

const getMe = async () => await 
  fetchURL("https://MY.SITE/api/users/me")
    .then((res) => res.data);

class loader {
  async EVERYonceWHENmethodCALLED() {
    this.ME = await getMe();
  }
  _me() {
    $("#me").html(`${this.ME.grade}${this.ME.number}[Tickets: ${self.ME.likeTicket}]`);
  } // ** likeTicket depends on ME **
  async _chart() {
    if ($("body").find("#chart").length) {
      const musicChart = await fetchURL(`https://MY.SITE/api/music/chart?&gender=${self.ME.gender}`);
      $("#chart").html(await listElementsOf(musicChart.data.list));
    } // ** listElementsOf depends on ME ( It lets me know what musics I 'liked' to ) **
  }
  async me() {
    await this.EVERYonceWHENmethodCALLED();
    this._me();
  }
  async chart() {
    await this.EVERYonceWHENmethodCALLED();
    await this._chart();
  }
  async search(q) {
    if ($("body").find("#searchResult").length){
      if(q) $("#searchResult").attr("data-q", q);
      else q = $("#searchResult").attr("data-q");

      const searchResult = await fetchURL(`https://MY.SITE/api/music/search?q=${q}`);
      $("#searchResult").html(await listElementsOf(searchResult));
    }
  }
  async meAndChart() {
    await this.EVERYonceWHENmethodCALLED();
    this._me();
    await this._chart();
  }
  async loadEverything() {
    await this.meAndChart();
    await this.search();
  }
}
GOTO 0
  • 42,323
  • 22
  • 125
  • 158