React Javascript Handle Possible Null Data

I am using React to create a simple application that returns data from some API. I'm not sure what is the best way to handle fields when some of them don't return. For example, Let's say JSON data is returned as shown below.

comicDetail : {
    name : iron man, 
    age: {
        comicAge: 35,   
    },
    favouriteFood: {
        fruit: {
            apple
        }
    }
    hobby: {
        favourite: {
            build machines        
        }
    }
    series: [iron man 1, iron man 2]
    relationship: {
        jane: iron man 1, 
        Mary: iron man 2
    }, 
    collection : {
            image : www.image1.com 
        }            
    }
}

      

My React code that displays data

renderComicDetail() {
    var cd = this.props.comicDetail;        
    if (!cd) {
        return (
            <div>No Data</div>
        )
    }
    const imageUrl = cd.collection.image
    return (
        <div>
            <div>age: {cd.age.comicAge}</div>                
            <div>favourite fruit: {cd.favouriteFood.fruit}</div>                
            <div>favourite hobby: {cd.hobby.favourite}</div>                
        </div>
    )
}

      

This code will break if any of cd.favouriteFood, cd.age, cd.hobby is undefined as I will read from undefined. (This will happen when not all of the fields return) What's the cleanest way to let me read the data and take care of the undefined case, so I don't read .fruit from undefined.

As I can think of it is to have check cases for every piece of json data for every item. But this seems to be messy and won't scalable as I might have data that looks like

+3


source to share


6 answers


You can specify a condition for rendering a component in JSX, your code will look something like this (assuming that if hobby or food is defined, then it will have properties that can be done):

var cd = this.props.comicDetail;        
    if (!cd) {
        return (
            <div>No Data</div>
        )
    }
    const imageUrl = cd.collection.image;


    return (
        <div>
            <div>age: {cd.age.comicAge}</div>                
            {cd.favouriteFood && <div>favourite fruit: {cd.favouriteFood.fruit}</div>}
            {cd.hobby && <div>favourite hobby: {cd.hobby.favourite}</div>}
        </div>
    )

      



I also advise you to either create a separate hobby and food component so that it can make your code more readable and reusable. But it definitely depends on your specific use.

+2


source


if you don't want to display undefined content, you can do it like this:

return (
        <div>
            {cd.age && cd.age.comicAge ? <div>age:{cd.age.comicAge}</div> : <div>No data</div> 
            } 
            {cd.favouriteFood && cd.favouriteFood.fruit ? <div>favourite fruit: {cd.favouriteFood.fruit}</div> : <div>No data</div> 
            } 
            {cd.hobby && cd.hobby.favourite ? <div>favourite hobby: {cd.hobby.favourite}</div> : <div>No data</div> 
            }                                            
        </div>
    )

      



or if you don't want that, create a separate function that checks for valid fields

if (!isValid(cd)) {
        return (
            <div>No Data</div>
        )
 }

isValid(obj){
  // check if all objects available are valid or not and return true or false as needed.
}

      

+1


source


How do I use the termed operator?

cd.age! == undefined? cd.age.comicAge: ''

0


source


You can use any JSON schema validator for this purpose, and there are many. for example jsonschema

In your case, you can create a schema something like this (for the first two properties)

var schema = {
"id": "/ComicDetail",
"type": "object",
"properties": {
    "name": {
        "type": "string"
    },

    "age": {
        "type": "object",
        "properties": {
            "comicAge": {
                "type": "integer"
            }
        }
    }
},
"required": ["name", "age"]
};

      

You can also combine two or more circuits to form a new circuit.

0


source


One way to access deep object using lodash. You can import lodash into your component.

_.get(cd, 'favouriteFood.fruit') || ''

      

https://lodash.com/docs/4.16.6#get

To clean up the code, you can also declare a function that takes your object (i.e. cd in your case) and a path (e.g. favoriteFood.fruit in your case) and returns a value from the function.

0


source


You can try your return statement like:

return (
        <div>
            { cd.age.comicAge && <div>age: {cd.age.comicAge }</div>}
            { cd.favouriteFood.fruit &&  <div>favourite fruit: {cd.favouriteFood.fruit}</div> }          

            {cd.hobby.favourite &&  <div>favourite hobby: {cd.hobby.favourite}</div>                
        </div>
    )

      

If your support is null or undefined, the right side of the condition is skipped.

-1


source







All Articles