Components

*onFirstMount: the first time a component with a specific instance or tree is mounted. If another instance with the same instance or tree is mounted afterwards, it will skip the onFirstMount function

Setup Components

DeclareReducer

Sets the reducer for its child TWRComponents required parent for all TWRComponents

Base Example:

<DeclareReducer reducer='admin'>
  <TWRIndex tree='users'/>
</DeclareReducer>

Two Way Components

TWRIndex

Returns an entire table from the frontend database

onFirstMount:

Backend: GET request to tree Frontend: state.set(tree, response)

instance(s):

return state.get(tree)

Base Example:

<TWRIndex tree='user'>
  <ListUsers/>
</TWRIndex>
function ListUsers(props){
  return <ul>
    {props.instances.map(user=>
      <li>{user.get('name)}</li>
    )}
}

Fake Response

<TWRIndex tree='user' response={[id: 1, name: 'Sam']}>
  <ListUsers/>
</TWRIndex>
function ListUsers(props){
  return <ul>
    {props.instances.map(user=>
      <li>{user.get('name)}</li>
    )}
}
*Instead of sending an ajax call, this component uses the response property to fill the frontend database*

TWRShow

Returns an instance from a table in the frontend database

onFirstMount:

Backend: GET request to tree/id Frontend: return state.setIn([tree, id], response)

instance:

return state.getIn([tree, id])

Base Example:

<TWRShow tree='user/1'>
  <ShowUser/>
</TWRIndex>
function ShowUser(props){
  const user = props.instance
  return <div>
    <h1>{user.get('name')}</h1>
    <h2>{user.get('occupation'}</h2>
  </div>
}

TWRCreate

when the component is submitted, it creates a new instance in the backend and frontend databases

onSubmit:

Backend: POST request to tree, ...formData Frontend: state.setIn([tree, response.id], ...formData)

instance:

return state.getIn([Substate, tree, randomId])

Base Example:

<TWRCreate tree='user'>
    <CreateUser noErrors/>  
</TWRShow>
function CreateUser(props){
  const {instance} = props
  return <div>
    <label>Name</label>
    <input name='name' type='text' placeholder='user name' />
    {instance.get('errors') ? 
    <span className='label-danger'>{instance.get('errors')}</span>
    :''}
    <button type='submit'>Save User Name</button>
  </div>
}

noErrors is a component property we use to tell the component not use the default display error functions. If we had not provided the noErrors prop, by default the component would have loaded a similar error code into the component

TWRUpdate

when the component is submitted, it updates the backend and frontend databases

onSubmit:

Backend: PUT request to instanceType/id, ...formData Frontend: state.updateIn([instanceType, id], ...formData)

instance:

return state.getIn([Substate, instanceType, randomId])

Base Example:

<TWRShow tree='user/1'>
    <UpdateUser/>  
</TWRShow>
function UpdateUser(props){
  const user = props.instance
  return <TWRUpdate instance={user}>
    <UpdateUserForm user={user}/>
  </TWRUpdate>
}
function UpdateUserForm(props){
  const {user, instance} = props

  return <div>
    <label>Name</label>
    <input name='name' type='text' defaultValue={user.get('name')} />
    {instance.get('errors') ? 
    <span className='label-danger'>{instance.get('errors')}</span>
    :''}
    <button type='submit'>Save User Name</button>
  </div>
}

Notice how we pass the user prop into the UpdateUserForm. This is because the TWRUpdate only passes the substate instance, not the actual instance, and the substate instance only holds error information noErrors is a component property we use to tell the component not use the default display error functions. If we had not provided the noErrors prop, by default the component would have loaded a similar error code into the component

TWRCreateChild

when the component is submitted, it creates a new instance with relational information in the backend and frontend databases

onSubmit:

Backend: POST request to childName, ...formData + {parent_id: parent.get('id')} Frontend: state.setIn([childName, response.id], ...formData).setIn([parentName, parentId], children.push(response.id))

instance:

return state.getIn([Substate, childName, randomId])

Base Example:

<TWRShow tree='user/1'>
  <CreateChild />
</TWRShow>

function CreateChild(props){
  const user = props.instance
  return <TWRCreateChild instance={user} childName='children'>
    <CreateChildForm />  
  </TWRCreateChild>
}

function CreateChildForm(props){
  return <div>
    <label>Name</label>
    <input name='name' type='text' placeholder='child name' />
    <button type='submit'>Save Child Name</button>
  </div>
}

*when this form is submitted, the post data will be {name: 'child name', user_id: user.get('id')}

TWRDestroy

when the component is submitted, it deletes the instance in the backend and frontend databases

onSubmit:

Backend: DELETE request to instance, ...formData Frontend: state.deleteIn([instance, instance.get('id')], ...formData)

instance:

return state.getIn([Substate, instanceName, randomId])

Base Example:

<TWRShow tree='user/1'>
  <DestroyUser />
</TWRShow>

function DestroyUser(props){
  const user = props.instance
  return <TWRDestroy instance={user}>
    <button type='submit'>Delete User</button>
  </TWRCreateChild>
}

*when this form is submitted successfully, the return data is not merged into the frontend database. Instead, the instance is simply removed from the database}

Frontend Components

returns a link that uses the instance type and id

Base Example:

<TWRShow tree='user/1'>
  <LinkToUser>
</TWRShow>

function LinkToUser(props){
  const user = props.instance
  return <TWRLink instance={user}>User</TWRCreateChild>
}
==> a href='...reducerName/user/1'

or

function LinkToUser(props){
  const user = props.instance
  return <TWRLink instance={user} rest='edit'>User</TWRCreateChild>
}
==> a href='.../reducerName/user/1/edit'

TWRShowFront, TWRIndexFront, TWRUpdateFront, TWRDestroyFront, TWRCreateChildFront

The exact same as the Two Way components but without the backend ajax calls

results matching ""

    No results matching ""