0

In this case I created a recursive promise function that is used to call different api urls. How do make the switch-case option in this code not too long?

let listUrl: Array<string> = ['URL-1', 'URL-2', 'URL-3', 'URL-n']

const rpcCall = async (baseURL: string) => {
switch (baseURL) {
    case 'URL-1':
        return new Promise((_resolve, reject) => fetch(baseURL)
            .then(resolve => resolve.status !== 200 || 201 ? Promise.reject() : resolve)
            .catch(reject)
        );
    case 'URL-2':
        return new Promise((_resolve, reject) => fetch(baseURL)
            .then(resolve => resolve.status !== 200 || 201 ? Promise.reject() : resolve)
            .catch(reject)
        );
    case 'URL-3':
        return new Promise((_resolve, reject) => fetch(baseURL)
            .then(resolve => resolve.status !== 200 || 201 ? Promise.reject() : resolve)
            .catch(reject)
        );
    case 'URL-n':
        return new Promise((_resolve, reject) => fetch(baseURL)
            .then(resolve => resolve.status !== 200 || 201 ? Promise.reject() : resolve)
            .catch(reject)
        );
    default:
        return Promise.reject();
  }
 }
const checkToken = async (index = 0): Promise<string> => {
new Promise((res, rej) =>
    rpcCall(listUrl[index])
        .then(res)
        .catch((reject) => {
            if (index < baseUrl.length && reject) {
                return checkToken(index + 1)
                    .then(res)
                    .catch(rej);
            } else {
                rej();
            }
        })
);
return listUrl[index]
}

I mean the best practice method for the options

Fery1320
  • 127
  • 1
  • 7

1 Answers1

1

Your URLs cases are all the same, so they can be combined. You should also avoid the explicit Promise construction antipattern. 200 || 201 will not properly compare against both values either. The resolver function is also not the same as the Response object from fetch - better to name the parameter appropriately.

You don't need to construct another Promise in checkToken either - and that function also looks broken because it's creating a Promise that isn't being used anywhere. Another problem is that a Response object isn't a string; : Promise<string> is not an accurate typing. Perhaps you meant to use response.text() and something like

let listUrl: Array<string> = ['URL-1', 'URL-2', 'URL-3', 'URL-n']

const rpcCall = (baseURL: string) => {
    const urls = ['URL-1', 'URL-2', 'URL-3', 'URL-n'];
    if (!urls.includes(baseURL)) {
        return Promise.reject();
    }
    return fetch(baseURL)
        .then(response => {
            if (response.status !== 200 && response.status !== 201) {
                throw new Error();
            }
            return response.text();
        });
};
const checkToken = async (index = 0): Promise<string> => {
    return rpcCall(listUrl[index])
        .catch((error) => {
            if (index < listUrl.length && error) {
                return checkToken(index + 1)
            } else {
                throw new Error(error);
            }
        });
};

Since this is TypeScript, you could also consider changing rpcCall to require that the string passed is one of the permitted URLs, thus forcing the caller to validate the potential argument first.

const urls = ['URL-1', 'URL-2', 'URL-3', 'URL-n'];
const rpcCall = (baseURL: typeof urls[number]) => {
    return fetch(baseURL)
        // etc
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thanks for the answer, besides, I'm a newbie in typescript, but your code doesn't work, there's still an error – Fery1320 Dec 07 '22 at 09:45
  • What exactly is the problem you're running into? Your original code was riddled with errors so I'm not surprised, but nothing's standing out as problematic to me in the code in the answer – CertainPerformance Dec 07 '22 at 15:30