Search code examples
javascriptnode.jsmarko

Marko JS on-submit


I can't get this to work, it will not console.log(this.stat.first_name) , I need to know how to access the input form values that are entered so I can change state and then make an axios post request in the postSubmit function. I am doing the console.log first to test it and get data movement correct.

Anything will help.

First question was deleted, this is a repost as I did not figure the problem out.

class {
  onCreate() {
    this.state = {
      first_name: null,
      last_name: null,
      email: null,
      address: null,
      phone_number: null,
      email_promotion_optin: false
    };
  }
  postSubmit(event) {
    event.preventDefault();
    this.state.first_name = event.target.name.first_name;
    console.log(this.state.first_name);
  }
}

<form on-click('postSubmit')>
  <fieldset>
    <legend> Create Customer</legend>
      <div>
        <label>
          First Name: <input type="text" name="first_name">
        </label>
      </div>
      <div>
        <label>
          Last Name: <input type="text" name="last_name">
        </label>
      </div>
      <div>
        <label>
          Email: <input type="text" name="email">
        </label>
      </div>
      <div>
        <label>
          Address: <input type="text" name="address">
        </label>
      </div>
      <div>
        <label>
          Phone Number: <input type="text" name="phone_number">
        </label>
      </div>
      <div>
        <label>
          Submit <input type="submit">
        </label>
      </div>
   </fieldset>
</form>

UPDATE!!!!!!:

I have come up with this from MarkoJS documentation, but still no luck. I may be on the right route or I may be polluting my code with a lot of unnecessary crap.

$ const axios = require('axios');

class {
  onCreate() {
    this.state = {
        first_name: '',
        last_name: '',
        email: '',
        address: '',
        phone_number: '',
        email_promotion_optin: false
    };
  }

  onFirstNameInput () {
    this.state.first_name = this.getEl('firstName').value;
  }

  onLastNameInput () {
    this.state.last_name = this.getEl('lastName').value;
  }

  onEmailInput () {
    this.state.email = this.getEl('email').value;
  }

  onAddressInput () {
    this.state.address = this.getEl('address').value;
  }

  onPhoneNumberInput () {
    this.state.phone_number = this.getEl('phoneNumber').value;
  }

  postSubmit() {
    axios.post('/api/v1/customers', this.state)
      .then(function (response) {
        console.log(response);
      })
    .catch(function (error) {
      console.log(error);
    });
  }

}



<form>
  <fieldset>
    <legend> Create Customer</legend>
    <div>
      <label>
        First Name: <input type="text" key="firstName" on-input('onFirstNameInput')>
      </label>
    </div>
    <div>
      <label>
        Last Name: <input type="text" key="last_name" on-input('oneLastNameInput')>
      </label>
    </div>
    <div>
      <label>
        Email: <input type="text" key="email" on-input('onEmailInput')>
      </label>
    </div>
    <div>
      <label>
        Address: <input type="text" key="address" on-input('onAddressInput')>
      </label>
    </div>
    <div>
      <label>
        Phone Number: <input type="text" key="phone_number" on-input('onPhoneNumberInput')>
      </label>
    </div>
  </fieldset>
  <div>
    <button on-click('postSubmit')>Submit</button>
  </div>
</form>

Solution

  • I looked into the issue. The reason that the code is not working as expected is that the properties on the this.state object are not defined as enumerable. MarkoJS uses Object.defineProperty to create getters and setters for the state properties, but it is not explicitly setting the enumerable property to true so it is defaulting to false. I think we should fix this and opened up a GitHub issue to discuss: https://github.com/marko-js/marko/issues/964

    In the meantime, I recommend the following workaround to explicitly copy over the properties that should be submitted with the HTTP post:

    postSubmit() {
      var request = {
        first_name: this.state.first_name,
        last_name: this.state.last_name,
        email: this.state.email,
        address: this.state.address,
        phone_number: this.state.phone_number,
        email_promotion_optin: this.state.email_promotion_optin
      }
    
      axios.post('/api/v1/customers', request)
        .then(function (response) {
          console.log(response);
        })
      .catch(function (error) {
        console.log(error);
      });
    }