Changing recived data in Promise React

Viewed 30

My React app recieves date in the following JSON-format:

[
{"date":"20201001","time":"001100"},
{"date":"20201001","time":"001200"},
{"date":"20201001","time":"001300"}
]

I want to save date and time to React state in normal format - date plus time. So it should be only date like this:

[
{"date":"2020-10-01 00:11:00"},
{"date":"2020-10-01 00:12:00"},
{"date":"2020-10-01 00:13:00"}
]

Here is my App.js code:


import React from 'react';
import { render } from 'react-dom';
import { timeParse } from "d3-time-format";

class MyComponent extends React.Component {

    constructor(props) {
        super(props);
        this.state = {datas: []};
    }

    componentDidMount() {
        this.getAllData();
    }

    getAllData() {
        fetch("http://localhost:8080/data")
            .then(response => response.json())
            .then((data) => { data = tt(data)})
            .then((data) => {
                this.setState({datas: data});
            });
    };

    render() {
        if (this.state == null) {
            return <div>Loading data...</div>
        }
        return (
            <div>{this.state.datas ? this.state.datas.toString() : 'No data yet...'}</div>
        )
    }
}

function tt(d) {
    d.date = timeParse(d.date+d.time);
    return d;
};

const parseDateTime = timeParse("%Y%d%m%H%M%S");

render(
    <MyComponent />,
    document.getElementById("root")
);

export default MyComponent;

I believe something wrong in the following line of code:

.then((data) => { data = tt(data)})

but cant understand what.

I always get unmodified date and time, same format it is recieved from server.

1 Answers

You are not returning the value from .then((data) => { data = tt(data)}). Return the new DateTime you are computing for the next then-able in the Promise chain.

If data is an array then you will need to map the data and call the tt utility function on each element object.

.then((data) => {
  return data.map(tt);
})

Update

You are parsing the date-time from an input format, but you need to also format an output. Instead of mutating the mapped data elements you will want to return a new object with date property only.

import { timeFormat, timeParse } from "d3-time-format";

...

const parseDateTime = timeParse("%Y%d%m%H%M%S");
const formatDateTime = timeFormat("%Y-%d-%m %H:%M:%S");

const tt = (d) => ({
  date: formatDateTime(parseDateTime(d.date + d.time))
});

...

getAllData() {
  fetch("http://localhost:8080/data")
    .then((response) => response.json())
    .then((datas) => datas.map(tt))
    .then((datas) => {
      this.setState({ datas });
    });
}

I suggest also adding a separate loading state since the datas state is a defined empty array, the state won't be null.

Full Example:

const parseDateTime = timeParse("%Y%d%m%H%M%S");
const formatDateTime = timeFormat("%Y-%d-%m %H:%M:%S");

const tt = (d) => ({
  date: formatDateTime(parseDateTime(d.date + d.time))
});

class MyComponent extends React.Component {
  state = {
    datas: [],
    loading: false
  };

  componentDidMount() {
    this.getAllData();
  }

  getAllData() {
    this.setState({ loading: true });
    fetch("http://localhost:8080/data")
      .then((response) => response.json())
      .then((datas) => datas.map(tt))
      .then((datas) => {
        this.setState({ datas });
      })
      .finally(() => this.setState({ loading: false }));
  }

  render() {
    if (this.state.loading) {
      return <div>Loading data...</div>;
    }
    return (
      <div>
        {this.state.datas.length
          ? JSON.stringify(this.state.datas)
          : "No data yet..."}
      </div>
    );
  }
}

Edit changing-recived-data-in-promise-react

Related