da_vinci
da_vinci

Reputation: 21

setState of entire object loaded from json file | ReactJS

This function is taken from another question here in StackOverflow I've found about loading data from a file, I couldn't find it and to give credits

 function loadFile() {
    var input, file, fr;

    if (typeof window.FileReader !== 'function') {
      alert("The file API isn't supported on this browser yet.");
      return;
    }

    input = document.getElementById('fileInput');
    if (!input) {
      alert("Um, couldn't find the fileinput element.");
    }
    
    else if (!input.files) {
      alert("This browser doesn't seem to support the `files` property of file inputs.");
    }
    else if (!input.files[0]) {
      alert("Please select a file before clicking 'Load'");
    }
    else {
      file = input.files[0];
      fr = new FileReader();
      fr.onload = receivedText;
      fr.readAsText(file);
    }

    function receivedText(e) {
      let lines = e.target.result;
      var newArr = JSON.parse(lines);
    
      console.log(newArr.text_box);
      var newState ={
            integration_time: newArr.text_box.integration_time_micro_sec, 
            x_axis_resulotion: newArr.text_box.x_axis_resulotion,
            y_axis_resulotion: newArr.text_box.y_axis_resulotion,
            delay_between_pixels_milisec: newArr.text_box.delay_between_pixels_milisec,
            results_directory: newArr.text_box.results_directory,
            config_file_name: ""
      }
      
      console.log(newState);
      alert(newState.integration_time);
      //This pops up the CORRECT data I want to update
      return {newState};
    }
  }
class App extends Component {
  state = {
    integration_time:configData.text_box.integration_time_micro_sec,//configData.integration_time_micro_sec,
    x_axis_resulotion: configData.text_box.x_axis_resulotion,
    y_axis_resulotion:configData.text_box.y_axis_resulotion,
    delay_between_pixels_milisec: configData.text_box.delay_between_pixels_milisec,
    results_directory: configData.text_box.results_directory,
    config_file_name: ""

    // Example for working handle for changing the value of integration_time
    handleIntegrationTimeInput = e => {
        this.setState({integration_time: e.target.value});
    };
    
    handleLoadConfigFile = e =>{
        loadFile();
        alert(this.state.integration_time); 
        //This pops up the OLD data, the new state wasn't assigned to the state...
    }; 
render(){
return(
//my HTML page as JS
            <input name="loadedConfigFile" id = 'fileInput' type="file"/>
            <input 
            name= "loadConfigButton"
            type= "button"
            id = "buttonLoad"
            value= "Load"
            onClick={this.handleLoadConfigFile}/> 

);
 }
}
export default App;

Im new in JS, and I might not understand well the state/object properties very well. It seems that my newState is maybe a local object or something like that in which I cannot assign it to this.state. I've read a lot about bind(), and the meaning of this, but I got very confused. How can I pass and change the state according to my .json data?

Upvotes: 0

Views: 304

Answers (1)

dave
dave

Reputation: 64657

Try this - I made loadFile return a promise so you can easily get to the return value from receivedText, then in the JSX portion we await the promise to get the new state, and then call setState with the returned state.

    function loadFile() {
        return new Promise((resolve, reject) => {
            var input, file, fr;

            if (typeof window.FileReader !== 'function') {
                alert("The file API isn't supported on this browser yet.");
                return;
            }

            input = document.getElementById('fileInput');
            if (!input) {
                alert("Um, couldn't find the fileinput element.");
            } else if (!input.files) {
                alert("This browser doesn't seem to support the `files` property of file inputs.");
            } else if (!input.files[0]) {
                alert("Please select a file before clicking 'Load'");
            } else {
                file = input.files[0];
                fr = new FileReader();
                fr.onload = receivedText;
                fr.readAsText(file);
            }

            function receivedText(e) {
                let lines = e.target.result;
                var newArr = JSON.parse(lines);

                console.log(newArr.text_box);
                var newState = {
                    integration_time: newArr.text_box.integration_time_micro_sec,
                    x_axis_resulotion: newArr.text_box.x_axis_resulotion,
                    y_axis_resulotion: newArr.text_box.y_axis_resulotion,
                    delay_between_pixels_milisec: newArr.text_box.delay_between_pixels_milisec,
                    results_directory: newArr.text_box.results_directory,
                    config_file_name: ""
                }

                console.log(newState);
                alert(newState.integration_time);
                //This pops up the CORRECT data I want to update
                resolve(newState);
            }
        });
    }

    class App extends Component {
        state = {
            integration_time: configData.text_box.integration_time_micro_sec, //configData.integration_time_micro_sec,
            x_axis_resulotion: configData.text_box.x_axis_resulotion,
            y_axis_resulotion: configData.text_box.y_axis_resulotion,
            delay_between_pixels_milisec: configData.text_box.delay_between_pixels_milisec,
            results_directory: configData.text_box.results_directory,
            config_file_name: ""

            // Example for working handle for changing the value of integration_time
            handleIntegrationTimeInput = e => {
                this.setState({
                    integration_time: e.target.value
                });
            };

            handleLoadConfigFile = async (e) => {
                const newState = await loadFile();
                this.setState(newState, () => {
                    alert(this.state.integration_time);
                });
                
                //This pops up the OLD data, the new state wasn't assigned to the state...
            };
            render() {
                return (
                    //my HTML page as JS
                    <input
                      name = "loadedConfigFile"
                      id = 'fileInput'
                      type = "file"
                    />
                    <input
                      name = "loadConfigButton"
                      type = "button"
                      id = "buttonLoad"
                      value = "Load"
                      onClick={this.handleLoadConfigFile}
                    /> 

                );
            }
        }
        export default App;

Upvotes: 1

Related Questions