foxhound87 / mobx-react-form-demo

Demo of MobX React Form
https://foxhound87.github.io/mobx-react-form/demo.html
82 stars 41 forks source link

_myForm2.default is not a constructor #6

Closed Itachi-Uchiha78 closed 7 years ago

Itachi-Uchiha78 commented 7 years ago

Hi,

mobx and react newbie here...I'm trying to build a super simple example to catch the basics of this library and realize if this could be used by my team.

I've started from a creat-react-app, modded to be a mobx (plus decorators) project this way: https://swizec.com/blog/mobx-with-create-react-app/swizec/7158

Then, I've installed' mobx-react-form' and 'validator.js' via npm. That should fit the requirements.

After that, i've followed the instruction of the "Automagically..." page, but something went wrong.

I've made a MyForm.js that looks like this:

import MobxReactForm from 'mobx-react-form';

import validatorjs from 'validatorjs';

const plugins = { dvr: validatorjs };

const fields = [{
  name: 'email',
  label: 'Email',
  placeholder: 'Insert Email',
  rules: 'required|email|string|between:5,25',
}, {
  name: 'password',
  label: 'Password',
  placeholder: 'Insert Password',
  rules: 'required|string|between:5,25',
}, {
  name: 'passwordConfirm',
  label: 'Password Confirmation',
  placeholder: 'Confirm Password',
  rules: 'same:password',
}];
class MyForm extends MobxReactForm {

  onSuccess(form) {
    alert('Form is valid! Send the request here.');
    // get field values
    console.log('Form Values!', form.values());
  }

  onError(form) {
    // get all form errors
    console.log('All form errors', form.errors());
    // invalidate the form with a custom error message
    form.invalidate('This is a generic error message!');
  }
}

export default new MyForm({ fields }, { plugins });

Then made another file called mobx-forms-test.js that contains:

import validatorjs from 'validatorjs';
import MyForm from './myForm'; 
import React from 'react';
import { observer } from 'mobx-react';

const form = new MyForm();
export default observer(({ form }) => (
  <form onSubmit={form.onSubmit}>
    <label htmlFor={form.$('username').id}>
      {form.$('username').label}
    </label>
    <input {...form.$('username').bind()} />
    <p>{form.$('username').error}</p>

    <button type="submit" onClick={form.onSubmit}>Submit</button>
    <button type="button" onClick={form.onClear}>Clear</button>
    <button type="button" onClick={form.onReset}>Reset</button>

    <p>{form.error}</p>
  </form>
));

And finally in main App.js I've done the final import:

import React, { Component } from 'react';
import FormMobx from './mobx-forms-test' 
import './App.css'; 

class App extends Component {

  render() {
    return (

      <div className="App">

            <div className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <h2>Welcome to React</h2>
            </div>

            <p className="App-intro">
              To get started, edit <code>src/App.js</code> and save to reload.
            </p>  
                <FormMobx/> 
       </div> 
    );
  }
}

export default App;

But the console of Chrome reports this error:

Uncaught TypeError: _myForm2.default is not a constructor
    at Object.<anonymous> (mobx-forms-test.js:8)
    at __webpack_require__ (bootstrap c055823…:555)
    at fn (bootstrap c055823…:86)
    at Object.<anonymous> (App.js:7)
    at __webpack_require__ (bootstrap c055823…:555)
    at fn (bootstrap c055823…:86)
    at Object.<anonymous> (index.js:3)
    at __webpack_require__ (bootstrap c055823…:555)
    at fn (bootstrap c055823…:86)
    at Object.<anonymous> (bootstrap c055823…:578)
(anonymous) @ mobx-forms-test.js:8
__webpack_require__ @ bootstrap c055823…:555
fn @ bootstrap c055823…:86
(anonymous) @ App.js:7
__webpack_require__ @ bootstrap c055823…:555
fn @ bootstrap c055823…:86
(anonymous) @ index.js:3
__webpack_require__ @ bootstrap c055823…:555
fn @ bootstrap c055823…:86
(anonymous) @ bootstrap c055823…:578
__webpack_require__ @ bootstrap c055823…:555
(anonymous) @ bootstrap c055823…:578
(anonymous) @ bootstrap c055823…:578
webpackHotDevClient.js:198 ./src/App.js

c:\Users\Black Jack\Desktop\QuickWebDevelop\mobxtest\src\App.js
  6:8  warning  'RemoteStoreInsertRow' is defined but never used  no-unused-vars

✖ 1 problem (0 errors, 1 warning)

printWarnings @ webpackHotDevClient.js:198
handleWarnings @ webpackHotDevClient.js:211
connection.onmessage @ webpackHotDevClient.js:258
EventTarget.dispatchEvent @ eventtarget.js:49
(anonymous) @ main.js:274
SockJS._transportMessage @ main.js:272
EventEmitter.emit @ emitter.js:44
WebSocketTransport.ws.onmessage @ websocket.js:35

Can u point me to the right direction?

Thanks!

foxhound87 commented 7 years ago

You are trying to instantiate the object two times. You should remove new from the component file (just pass it through the components instead) because you already have a Form instance by calling new in MyForm.js

Itachi-Uchiha78 commented 7 years ago

Oh I see...but if I rework as u mentioned from this:

export default new MyForm({ fields }, { plugins });

to:

export default MyForm({ fields }, { plugins });

I have:

Uncaught TypeError: Cannot call a class as a function
    at _classCallCheck (myForm.js:4)
    at MyForm (myForm.js:24)
    at Object.<anonymous> (myForm.js:40)
    at __webpack_require__ (bootstrap ebea370…:555)
    at fn (bootstrap ebea370…:86)
    at Object.<anonymous> (mobx-forms-test.js:2)
    at __webpack_require__ (bootstrap ebea370…:555)
    at fn (bootstrap ebea370…:86)
    at Object.<anonymous> (App.js:7)
    at __webpack_require__ (bootstrap ebea370…:555)

I've also tried to modify mantaining the new keyword in 'MyForm.js' revorking 'mobx-forms-test.js' this way:

import validatorjs from 'validatorjs';
import MyForm from './myForm'; 
import React from 'react';
import { observer } from 'mobx-react';

//const form = new MyForm();
export default observer(({ MyForm }) => (
  <MyForm onSubmit={MyForm.onSubmit}>
    <label htmlFor={MyForm.$('username').id}>
      {MyForm.$('username').label}
    </label>
    <input {...MyForm.$('username').bind()} />
    <p>{MyForm.$('username').error}</p>

    <button type="submit" onClick={MyForm.onSubmit}>Submit</button>
    <button type="button" onClick={MyForm.onClear}>Clear</button>
    <button type="button" onClick={MyForm.onReset}>Reset</button>

    <p>{MyForm.error}</p>
  </MyForm>
));

but console gaves me:

ReactDOMComponentTree.js:113 Uncaught TypeError: Cannot read property '__reactInternalInstance$2nbqlddibzi' of null
    at Object.getClosestInstanceFromNode (ReactDOMComponentTree.js:113)
    at findParent (ReactEventListener.js:38)
    at handleTopLevelImpl (ReactEventListener.js:67)
    at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:140)
    at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
    at Object.batchedUpdates (ReactUpdates.js:97)
    at dispatchEvent (ReactEventListener.js:147)

Also tried leaving last class as it was adding inside the form tag:

<MyForm form={form} />

But:

mobx-forms-test.js:10 Uncaught TypeError: Cannot read property 'onSubmit' of undefined

foxhound87 commented 7 years ago

Please read back my previous message.

I meant removing const form = new MyForm() from your mobx-forms-test.js component file.

You are getting Cannot read property of null/undefined because you are not passing the props in your component or importing the form package correctly.

Furthermore, the package doesn't provide a React Component but a MobX Store Object and cannot be used as an HTML tag.