0

I have a JSON file:

 [
  {
   "id": 1,
   "color": "Blue",
   "availability": false
  },
  {
   "id": 2,
   "color": "Pink",
   "availability": true
  }
 ]

What I would like to achieve is for the JSON with "availability : true" to automatically appear above the "availability : false". So that the pink appears above the blue like this:

enter image description here

This is my code so far which simply displays them in the same order as the JSON file:

import React, { Component } from 'react';
import './styles.css'

class GetOnlinePosts extends Component {
constructor(props){
    super(props);
    this.state = {
        error : null,
        isLoaded : false,
        posts : []          
    };
}
componentDidMount(){
    fetch("https://api.myjson.com")
    .then( response => response.json())
    .then(
        (result) => {
            this.setState({
                isLoaded : true,
                posts : result
            });
        },
        (error) => {
            this.setState({
                isLoaded: true,
                error
            })
        },
    )
}
render() {
    const {error, isLoaded, posts} = this.state;
    if(error){
        return <div>Error in loading</div>
    }else if (!isLoaded) {
        return <div>Loading ...</div>
    }else{
        return(
            <div>
                <div className="tiles">
                {
                    posts.map(post => (
                        <div key={post.id}>
                            <div className="tile">
                                <p className="color">{post.color}</p>
                            </div> 
                       </div>
                      ))
                    }
                </div>
            </div>
        );
    }
  }
}

export default GetOnlinePosts;

I am unsure of how to achieve this and have struggled to find any suggestions so far so any help would be great.

RH2019
  • 119
  • 10
  • `.sort()` them first on `availability` before you call `.map()` – Andreas Nov 27 '19 at 13:26
  • Maybe you can separate this array of objects in 2 other arrays, one that is the available ones and other with unavailable ones (using `map`, `filter` or something like that), then run just the available ones first, that way the "pink" ones will come first. Or just `.sort` the array by `availability` – Calvin Nunes Nov 27 '19 at 13:26
  • You need to [`.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) your data before returning from your `componentDidMount` function. – Nicolas Nov 27 '19 at 13:28
  • `[...posts].sort((a, b) => b.availability - a.availability).map(...)` – adiga Nov 27 '19 at 13:28

2 Answers2

1

var data = [{
    "id": 1,
    "color": "Blue",
    "availability": false
  },
  {
    "id": 2,
    "color": "Pink",
    "availability": true
  },
  {
    "id": 3,
    "color": "Pink",
    "availability": true
  },
  {
    "id": 4,
    "color": "Pink",
    "availability": false
  }, {
    "id": 5,
    "color": "Pink",
    "availability": true
  }
]
//unordered
data.sort(val => val.availability ? -1 : 1) //simple one line sort function for boolean
console.log(data);

// ordered based on your default array order
data = [{
    "id": 1,
    "color": "Blue",
    "availability": false
  },
  {
    "id": 2,
    "color": "Pink",
    "availability": true
  },
  {
    "id": 3,
    "color": "Pink",
    "availability": true
  },
  {
    "id": 4,
    "color": "Pink",
    "availability": false
  }, {
    "id": 5,
    "color": "Pink",
    "availability": true
  }
]

data.sort((a, b) => b.availability - a.availability);
console.log(data);
adiga
  • 34,372
  • 9
  • 61
  • 83
pavan kumar
  • 823
  • 6
  • 15
  • This will not keep the relative order of all the `true` values – adiga Nov 27 '19 at 13:39
  • what do you mean by relative order, can you be more specific? – pavan kumar Nov 27 '19 at 13:41
  • Provide different `id` to each object. The `true` values in the resulting array will not be in the same order as in the original array. `sort`'s callback has 2 parameters. Here, only the first parameter is considered and it results in inconsistent sorting – adiga Nov 27 '19 at 13:42
  • ok so you want to retain order right?... – pavan kumar Nov 27 '19 at 13:48
  • If you give the objects ids from 1 to 5, then `5` is at the top (in Chrome). It should be 2-3-5 in the sorted array because that's how the objects are placed in the input. `.sort((a, b) => b.availability - a.availability)` will keep the original relative order – adiga Nov 27 '19 at 14:08
  • @adiga i have also added the code for what you asked, the approach is a bit unconventional though, but works fine... – pavan kumar Nov 27 '19 at 14:12
0

You can filter the two sets, create a new array and then render it.

import React, { Component } from 'react';
import './styles.css'

class GetOnlinePosts extends Component {
constructor(props){
    super(props);
    this.state = {
        error : null,
        isLoaded : false,
        posts : []          
    };
}
componentDidMount(){
    fetch("https://api.myjson.com")
    .then( response => response.json())
    .then(
        (result) => {
            this.setState({
                isLoaded : true,
                posts : result
            });
        },
        (error) => {
            this.setState({
                isLoaded: true,
                error
            })
        },
    )
}
render() {
    const {error, isLoaded, posts} = this.state;
    const orderedPosts = [...posts.filter((post) => post.availability), ...posts.filter((post) => !post.availability)]
    if(error){
        return <div>Error in loading</div>
    }else if (!isLoaded) {
        return <div>Loading ...</div>
    }else{
        return(
            <div>
                <div className="tiles">
                {
                    orderedPosts.map(post => (
                        <div key={post.id}>
                            <div className="tile">
                                <p className="color">{post.color}</p>
                            </div> 
                       </div>
                      ))
                    }
                </div>
            </div>
        );
    }
  }
}

export default GetOnlinePosts;
Ayushya
  • 1,862
  • 1
  • 10
  • 15