What does the question mark mean in the return statement in JS?

Viewed 4479

I've got a function service the using data from loader and transform it in the right way for me and then return new data I have a suggestion to use '?' before returning data in transformation that can make some sense if there will not be data from loader:


export default async function serviceInputSearch(url) {
  const data = await new DataLoader(url).get();
  return data?.data.results;
}

I cannot find any information in google about this '?' in return statement? What does it mean?

5 Answers

This is called optional chaining. You can find more information about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining.

But, given your example, the gist of it is that the question mark validates if there is a valid "data" object. If you do not have the question mark there and there is no data object or it is null, then an error will be thrown in the lines of "Cannot read the property data of 'undefined'".

This is called as Optional chaining

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

// you can use it to check if the property is exist in the object
const dogName = adventurer.dog?.name; //same as adventurer.dog && adventurer.dog.name ? adventurer.dog.name : undefined;
console.log(dogName); //undefined

or else you can use it for check/call the existence of function of inside a object

// if someNonExistentMethod is exists in the adventurer Object call it.
console.log(adventurer.someNonExistentMethod?.());

Syntax is

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  },
  skills: ['jump']
};

obj.val?.prop => //Optional chaining
    ex: adventurer.dog?.name

obj.val?.[expr] => //Optional chaining with expressions
    ex: const propertyName = 'name'; adventurer.dog?.[propertyName];

obj.arr?.[index] => //Array item access with optional chaining
    ex: adventurer.skills?.[0] //jump

obj.func?.(args) => //Optional chaining with function calls
    ex: adventurer.someNonExistentMethod?.()

Its the "optional chainging" operator.

Here an use case:

let obj = {};

console.log(obj?.person?.age);
console.log(obj.person.age);

It comes handy if you try to access an property that not there. Its undefined so you get the error cannot get xx of undefined

To prevent this error you put an ?. infront of it, it will return an undefined back rather then throwing an error

Here some examples:

let obj = {};


//method does not exist
console.log(obj.func?.())


let arr = ["tom"];
console.log(arr[2]?.name);


let matrix = [ [ 1 ], [ 2 ] ];
console.log(matrix[5]?.[3]);


let defaultName = obj?.name ?? "Tom";
console.log(defaultName);

reference

In Javascript, we would need to explicitly check every reference to make sure it’s defined. If we have a deeply nested reference within an object, it might look something like this:

let networkFetchResult = await fetch("https://myfriends.com/user/123").then(res => res.json());
// Let's assume that the first friend of our request user is our best friend
let bestFriendsName = networkFetchResult
  && networkFetchResult.data
  && networkFetchResult.data.user
  && networkFetchResult.data.user.friends
  && networkFetchResult.data.user.friends[0]
  && networkFetchResult.data.user.friends[0].name
  || "You don't have any friends!";

Instead you can just do

let networkFetchResult = await fetch("https://myfriends.com/user/123").then(res => res.json());
// Still assuming that our first friend is our best friend
let bestFriendsName = networkFetchResult?.data?.user?.friends?.[0]?.name || "You don't have any friends!";

Related