1

I'm quite new to react and i'm trying to get an object (session) from a server and edit it using a form and after changes being made, store it using a post to the server.

I've made a component that fetches data from the server and stores it into the state.

The problem is that the render section gives an error because it probably doesn't know the subfields of the state object yet. I'm referring to 'session.name' and a couple of other fields but that gives an error. (TypeError: this.state.session is null[Meer info])

class SessionFirstTab extends React.Component {
    constructor() {
        super();
        this.state = { 
            session: null,
            statechanged: false
        };  
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.getSessionData = this.getSessionData.bind(this)

    }

    componentDidMount() {
        this.getSessionData()
    }

    getSessionData() {
        var myHeaders = new Headers();
        myHeaders.append("Content-Type", 'application/x-www-form-urlencoded');
        myHeaders.append("x-access-token", 'eyJhbGciOiJIUzI1....');
        myHeaders.append("userid", "5904ab94835a710868d19fa2");
        myHeaders.append("id", this.props.sessionid);

        var myInit = { method: 'GET',
               headers: myHeaders,
               mode: 'cors',
               cache: 'default' };


       fetch('http://localhost:3000/api/session',myInit) 
      .then(function(response) {  
          if (response.status !== 200) {  
            console.log('Looks like there was a problem. Status Code: ' +  
              response.status); 
            return;  
          }
        //   Examine the text in the response  
         response.json().then(function(data) {  
         data => this.setState({session: data});

          });  
        }  
      )  
      .catch(function(err) {    
        console.log('Fetch Error', err);  
      });



    } //////////////END getSessionInfo


    handleChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;

        this.setState({ statechanged: true});
        this.setState({session: {[name]: value}});
    }


    handleSubmit(event) {
    // console.log(this.state.session.name);
        event.preventDefault();
    }



    render() {
        return (

     <article className="article">
    <h2 className="article-title">Edit Session </h2>

    <section className="box box-default">
      <div className="box-body padding-xl">

        <section className="box box-default">
          <div className="box-body no-padding">
           <Tabs>
    <Tab label="Properties" >
      <div style={styles}>

       <form role="form" onSubmit={this.handleSubmit}>





          <div className="divider divider-lg" />
    <div className="row">

      <div className="col-xl-6">
        <div className="box box-default">
          <div className="box-body">
            <div className="icon-box ibox-center">
              <div className="ibox-icon">
                <a href="javascript:;"><i className="material-icons">settings</i></a>
              </div>
              <h3>General</h3>
               <div className="form-group">
             <TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name"  floatingLabelFixed defaultValue={this.state.session.name} onChange={this.handleChange}/><br />
          </div>
1
  • I think the only thing you need to do is jus to check whether session is null or not. More or less: this.state.session === null ? 'nothing?' : this.state.session.name. Other strategy might be, if session is null then render some Loading text..., else render the stuff you need. Commented May 24, 2017 at 20:42

2 Answers 2

1

I think the only thing you need to do is just to check whether session is null or not. I usually use two approaches, always depending on what I need.

Approach 1:

if there is session, render session.name, else render a empty string.

<TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name"  floatingLabelFixed defaultValue={this.state.session !== null ? this.state.session.name : ''} onChange={this.handleChange}/>

This way forces you to check also inside your handlers. In your case you will have to check inside handleChange and also in handleSummit. So in my opinion, you should try with the second approach.

Approach 2:

If you have session, render the form, else render some loading graph

if(this.state.session){
  return (
    <form role="form" onSubmit={this.handleSubmit}>
      ... your staff here   
    </form>
  );
} else {
  return (
    <div>
      We are waiting for the session
    </div>
  );
}

Particularly, I would not store the whole session in the state, but I would store just the properties I needed. I mean, I would store this.state.name. Just for semantic and responsabilities concerns. Why? I'm supposing that your session has many things that the component does not need to know, so then it should not be there. But we could have a good discussion about that.

Hope It helps, If you feel like you need to clarify let me know, I will help.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi Facundo, thanks for your help! The error is gone. Now it hangs on 'waiting for the session'. It seems that the entity session stays null? When i log the 'data' object, it states: Object { _id: "5904ab26ab0104206cb6a409", name: "a good name", userid: "5904ab94835a710868d19fa2", sessioncode: "ABCDEF", producttype: "product1", tagline: "something", searchtags: "pizza", animationspeed: 35, __v: 0, moderatorfilter: false, 3 more… } So the data seems filled but it isn't put in the state probably? kind regards, steven
It seems you have a sintax error in your fetch, removing data => should solve the problem, but anymways, try debugging that promise in order to see if the session is being saved correctly in the state. But as you said, the problem is there
:) Found it. Changed it to: fetch('localhost:3000/api/session',myInit) .then(response => response.json()) .then(json => { console.log(json); this.setState({ session: json, }); }); and the page works now. Thanks for all your help! Have a good weekend!
0

You just need to handle when session is null. An easy solution would be:

render() {
    const session_name = this.state.session.name || '';
        return (

     <article className="article">
    <h2 className="article-title">Edit Session </h2>

    <section className="box box-default">
      <div className="box-body padding-xl">

        <section className="box box-default">
          <div className="box-body no-padding">
           <Tabs>
    <Tab label="Properties" >
      <div style={styles}>

       <form role="form" onSubmit={this.handleSubmit}>





          <div className="divider divider-lg" />
    <div className="row">

      <div className="col-xl-6">
        <div className="box box-default">
          <div className="box-body">
            <div className="icon-box ibox-center">
              <div className="ibox-icon">
                <a href="javascript:;"><i className="material-icons">settings</i></a>
              </div>
              <h3>General</h3>
               <div className="form-group">
             <TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name"  floatingLabelFixed defaultValue={session_name} onChange={this.handleChange}/><br />
          </div>

2 Comments

This example is not going to work due to session_name is filled with the whole session. And also, with the actual implementation It is going to have some issues when the handlers execute
Sorry, typo. Yes, it should be this.state.session.name || ''.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.