0

Here is my code:

function GETdynamoDBapi(phoneNumber) {
    return new Promise(function (resolve, reject) {
        fetch(
            'https://api?phoneNumber=' +
                phoneNumber
        )
            .then((res) => {
                return res.json();
            })
            .then((res) => {
                resolve(data);
            })
            .catch((err) => {
                reject(err);
            });
    });
}

I have tried following two case of with and without +. I have both '4100000000' and '+4100000000' data on my database table. Phone Number is defined as string in database.

let response = await GETdynamoDBapi('+4100000000'); //error return data
let response = await GETdynamoDBapi('4100000000'); //return date success

How can I handle the '+' sign? Thanks!

(edited)
I also tried to test the API https://api?phoneNumber=+4100000000 on Insomnia and it works well. But when I try following in my code, it cannot return any data.

        fetch(
            'https://api?phoneNumber=+4100000000'
        )
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Jess
  • 63
  • 6
  • handle what plus sign? is there a plus sign in `phoneNumber` variable? if so ... remove it – Jaromanda X Sep 30 '22 at 10:45
  • Apply proper URL encoding to the value. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent – CBroe Sep 30 '22 at 11:06

1 Answers1

1

You forgot to encode the value:

fetch(`https://api?phoneNumber=${encodeURIComponent(phoneNumber)}`)

This way, it will turn into e.g. phoneNumber=%2B1234567890 so that when decoding on the server it will turn back into +1234567890. The + may otherwise be interpreted as a space character on the server.

You should always encode query arguments, otherwise you will have a bug at the very least and a security vulnerability at the worst.

Another, more expressive way would be to use URLSearchParams:

fetch(`https://api?${new URLSearchParams({ phoneNumber })}`)

Or a URL object:

const url = new URL('https://api')
url.searchParams.set('phoneNumber', phoneNumber)
fetch(url)

Or, you could use a tagged template function like uri-tag:

import uri from 'uri-tag'

fetch(uri`https://api?phoneNumber=${phoneNumber}`)

On another note: You are using the explicit promise construction anti-pattern. There is no need for any new Promise because fetch already returns a promise, otherwise you couldn't do .then!

function GETdynamoDBapi (phoneNumber) {
  return fetch(`https://api?${new URLSearchParams({ phoneNumber })}`)
    .then(res => res.json())
}

Or you could make the function async and use await, then it would be even easier to maintain in case more logic is added and would be consistent with your other functions for which you apparently already use async/await:

async function GETdynamoDBapi (phoneNumber) {
  const response = await fetch(`https://api?${new URLSearchParams({ phoneNumber })}`)
  return await response.json()
}

Preemptive comment: Read here as for why I do use return await.

CherryDT
  • 25,571
  • 5
  • 49
  • 74