Ilya Trianggela
Ilya Trianggela

Reputation: 307

is there simple way to fetch more than one request

i want to do http request using fetch(). The request is more than one that from same domain (it's just different endpoint).

I made my code like this:

Get the first data(number of chapter and verse):

static getData(keyword) {

      return fetch(`https://api.banghasan.com/quran/format/json/cari/${keyword}/bahasa/id/mulai/0/limit/100`)
         .then(resolve => {
            return resolve.json()
         })
         .then(rj => {
            if (rj.status == 'ok') {
               return Promise.reject(`The "${keyword}" keyword is not found`);
            } else {
               return Promise.reject(`Something Wrong`)
            }
         })
         .catch(error => {
            return Promise.reject(error);
         })
   }

If getData return `resolve', there are the number of chapter and verses Then, get the verses:

   static async getAyat(surat, ayat) {
      return fetch(`https://api.banghasan.com/quran/format/json/surat/${surat}/ayat/${ayat}`)
         .then(resolve => {
            return resolve.json()
         })
         .then(rj => {
            if (rj.status == 'ok') {
               return Promise.resolve(rj.ayat.data);
            } else {
               return Promise.reject('Terjadi kesalahan')
            }
         })
         .catch(error => {
            return Promise.reject(error);
         })
   }

Last, get Notes, if the verse has something to explain

static getNote(num) {
      return fetch(`https://api.banghasan.com/quran/format/json/catatan/${num}`)
         .then(resolve => {
            return resolve.json()
         })
         .then(rj => {
            if (rj.status == 'ok') {
               return Promise.resolve(rj.catatan.teks)
            } else {
               return Promise.reject('Terjadi kesalahan')
            }
         })
         .catch(error => {
            return Promise.reject(error);
         })
   }

The code is works properly. I just wanna know, is there simple way to write it?

Upvotes: 0

Views: 49

Answers (1)

Jacob
Jacob

Reputation: 78840

Use a function. Ask yourself which parts are the same versus what is different, then take the parts that are different and make them parameters.

In your case, here's what's different:

  1. The arguments to the function
  2. The URL generation
  3. The data you extract from the response

So here's how you can create a function to encapsulate those differences:

const baseUrl = 'https://api.banghasan.com/quran/format/json';
const returnAllData = data => data;

function createFetchMethod(urlBuilder, dataExtractor = returnAllData) {
  return async (...params) => {
    const url = urlBuilder(...params);
    const response = await fetch(`${baseUrl}${url}`);
    if (!response.ok) {
      throw new Error("Something's wrong");
    }

    const json = await response.json();
    if (json.status !== 'ok') {
      throw new Error("Something's wrong");
    }

    return dataExtractor(json);
  }
}

The way you'd use this is to create your methods like this:

const getData = createFetchMethod(
  keyword => `/cari/${keyword}/bahasa/id/mulai/0/limit/100`
);
const getAyat = createFetchMethod(
  (surat, ayat) => `/surat/${surat}/ayat/${ayat}`,
  json => json.ayat.data
);
const getNote = createFetchMethod(
  num => `/catatan/${num}`,
  json => json.catatan.teks
);

These can now be called as before, only all the error handling is encapsulated. You can further customize by adding more parameters.

Note that one potential problem with your URL building code is if the parameters being injected aren't URL-safe, you need to call encodeURIComponent for them to escape special characters.

Upvotes: 1

Related Questions