Search code examples
arraysjsonreactjscockpit

Reactjs - Assigning json response to default array


I'm using react-image-gallery for displaying gallery. I need to load images from json response. My code follows,

let imagesArray = [
 {
    original: 'images/products/4.jpg'
 },
 {
    original: 'images/products/2.jpg'
 },
 {
    original: 'images/products/3.jpg'
 }
];

export default class Products extends React.Component {
  loadGallery () {
    var requestUrl = 'http://myurl';
    var myInit = { method: 'GET',
               mode: 'cors',
               cache: 'default' };
    fetch(requestUrl).then(response =>
      response.json().then(data => ({
          data: data,
          status: response.status
      })
    ).then(res => {
        let imagesArray = imagesArray.map((img,i)=>{ return {original: res.data[i].path.split(':')[1]}})
    }));
  }
   render() {
    return (
      <div className="products-page" onLoad={ this.loadGallery() }>
        <ImageGallery
          ref={i => this._imageGallery = i}
          items={imagesArray}/>
      </div>
    );
  }
}

I got an error of Uncaught (in promise) TypeError: Cannot read property 'map' of undefined

if I use let newArray = imagesArray.map((img,i)=>{ return {original: res.data[i].path.split(':')[1]}}) it will assign the value to newArray

Here how can I assign the json response to imagesArray?


Solution

  • If what I understand is correct you want to load a set of images and pass the data as array to ImageGallery component.

    There is also something wrong/undesired with your code:

    When you do this,

    <div className="products-page" onLoad={this.loadGallery()}>
    

    You will actually invoke the function loadGallery() on each render, instead you should only pass the function prototype.

    <div className="products-page" onLoad={this.loadGallery}>
    

    Below you will see another approach to implement your requirement. Here we will load the images and update Product component's state with new imagesArray from JSON response. So when the state updates, component re-renders and will pass the new data to ImageGallery component.

    const dummyImagesArray = [
      {
        original: 'images/products/4.jpg'
      },
      {
        original: 'images/products/2.jpg'
      },
      {
        original: 'images/products/3.jpg'
      }
    ];
    
    export default class Products extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          imagesArray: dummyImagesArray
        }
      }
    
      loadGallery () {
        var requestUrl = 'http://myurl';
        var myInit = { method: 'GET',
                   mode: 'cors',
                   cache: 'default' };
        fetch(requestUrl).then(response =>
          response.json().then(data => ({
              data: data,
              status: response.status
          })
        ).then(res => {
            const imagesArray = this.state.imagesArray.map((img,i) => { return { original: res.data[i].path.split(':')[1] }; });
            this.setState({ imagesArray });
        }));
      }
    
      render() {
        return (
          <div className="products-page" onLoad={this.loadGallery}>
            <ImageGallery
              ref={i => this._imageGallery = i}
              items={this.state.imagesArray}
            />
          </div>
        );
      }
    }