19

So, I'm trying to create form with Formik and Material UI. For all the fields everything is working as it should but the problem is with Autocomplete. I cannot find the way to populate the field from the localStorage. I tried everything, from putting the value props, inputValue, defaultValue, etc but nothing seems to work.

import React from 'react'
import { Grid } from '@material-ui/core'
import { Autocomplete } from '@material-ui/lab'
import { Formik, Form, Field } from 'formik'
import { TextField } from 'formik-material-ui'
import * as yup from 'yup'
import { nationality } from '../../constants/nationality'
import Button from '../Button/Button'

export default function ForeignAddress () {

  let localStorageData = localStorage.getItem('foreignAddress'),
    retrivedData = JSON.parse(localStorageData)


  const handleNextClick = () => {
    console.log('clicked next')
  }

  const handleBackClick = () => {
    console.log('clicked back')
  }

  const validationSchema = yup.object({
    streetName: yup.string().required('Street name is required'),
    streetNumber: yup.string().required('Street number is required'),
    postalCode: yup.string().required('Postal code is required'),
    city: yup.string().required('City is required'),
    country: yup.string().required('Country is required'),
  })

  console.log(retrivedData)

  return (
    <React.Fragment>
      <div className="pages-wrapper address">
        <Formik
          initialValues={retrivedData ? retrivedData : {streetName: '', streetNumber: '', postalCode: '', city: '', coAddress: '', country: ''}}
          onSubmit={(data) => {
            console.log(data)
            localStorage.setItem('foreignAddress', JSON.stringify(data))
            handleNextClick()
          }}
          validationSchema={validationSchema}
        >
          {({setFieldValue}) => (
            <Form>
              <Grid container spacing={3}>
                <Grid item xs={12} md={8}>
                  <Field component={TextField} name="streetName" label="Street Name" variant="outlined" fullWidth />
                </Grid>
                <Grid item xs={12} md={4}>
                  <Field component={TextField} name="streetNumber" label="Street Number" variant="outlined" fullWidth />
                </Grid>
                <Grid item xs={12} md={4}>
                  <Field component={TextField} name="postalCode" label="Postal Code" variant="outlined" fullWidth />
                </Grid>
                <Grid item xs={12} md={8}>
                  <Field component={TextField} name="city" label="City" variant="outlined" fullWidth />
                </Grid>
                <Grid item xs={12} md={6}>
                  <Field component={TextField} name="coAddress" label="C/O Address" variant="outlined" fullWidth />
                </Grid>
                <Grid item xs={12} md={6}>
                  <Autocomplete
                    id="foreignCountry"
                    className="country-select"
                    name="country"
                    options={nationality}
                    getOptionLabel={option => option.label}
                    onChange={(e, value) => {
                      console.log(value)
                      setFieldValue("country", value.code)
                    }}
                    renderInput={params => (
                      <Field component={TextField} {...params} name="country" label="Country" variant="outlined" fullWidth/>
                    )}
                  />
                </Grid>
              </Grid>
              <div className="button-wrapper">
                <Button label="Back" go="back" handleClick={handleBackClick}/>
                <Button label="Next" go="next" type="submit" />
              </div>
            </Form>
          )}
        </Formik>
      </div>
    </React.Fragment>
  )
}

EDIT:

Thanks to @Vencovsky i was able to get it done

in case someone in the future needs this here is the working code. Just change Autocomplete component to

<Autocomplete
  id="foreignCountry"
  className="country-select"
  name="country"
  options={nationality}
  getOptionLabel={option => option.label}
  defaultValue={values.country}
  onChange={(e, value) => {
    console.log(value)
    setFieldValue("country", value)
}}
  renderInput={params => (
    <Field component={TextField} {...params} name="country" label="Country" variant="outlined" fullWidth/>
)}
/>

and in the Formik props just add values prop

{({setFieldValue, values}) => (
   <Form>,...
utazabanje
  • 228
  • 1
  • 2
  • 9

1 Answers1

17

Edit:

There is a few thing you need to change.

First you can't just store the code to load it later, you need to store everything (the hole value object) from the options.

Change the initial value of country: '' to country: {code: "", label: "", phone: ""} which is all the default value of the options.

Then to load the value correctly you should pass value={values.country} where values comes from formik props.

And on onChange you should save the hole value onChange={(e, value) => {setFieldValue("country", value); }}

But you are also importing and using some wrong things like

  <Field
    component={TextField}
    {...params}
    name="country"
    label="Country"
    variant="outlined"
    fullWidth
  />

Where Field is form formik and TextField from formik material ui.

Not sure why you use it like that, but I have changed it.

Here is a working example

Vencovsky
  • 28,550
  • 17
  • 109
  • 176
  • Thanks for reply. But the values are changing, that's not the problem. What i'm trying to get is just to show the value from localStorage in Autocomplete Text Field. All other fields are getting populated. – utazabanje Dec 09 '19 at 14:19
  • What is not working? Can you please show how is the data from `localStorage`? – Vencovsky Dec 09 '19 at 14:22
  • {"streetName":"asd","streetNumber":"asd","postalCode":"sad","city":"asd","coAddress":"","country":"RS"}, and like i said, when component renders, all the fields are populated except autocomplete field. – utazabanje Dec 09 '19 at 14:41
  • @utazabanje check my edit, you are saving the data wrong – Vencovsky Dec 09 '19 at 14:50
  • no, still nothing. i've made a sandbox https://codesandbox.io/s/dank-https-tykxu so you can see whats wrong. Try clicking next, and look at the localStorage. You will se the country has value. After that try refreshing the page and you will se that all the fields gets updated except Country field. thanks again – utazabanje Dec 09 '19 at 15:07
  • @utazabanje your link is broken/empty – Vencovsky Dec 09 '19 at 15:08
  • @utazabanje please check my answer and my [codesandbox](https://codesandbox.io/s/pedantic-wright-3qy3g), now it's working – Vencovsky Dec 09 '19 at 15:23
  • @utazabanje if that solved your problem, please considerer upvoting and marking the answer as accepted, thanks ;) – Vencovsky Dec 09 '19 at 15:24
  • Ops, Just a sec – Vencovsky Dec 09 '19 at 15:39
  • @utazabanje i realized you made a big mistake in the imports, now it's working and it's fixed – Vencovsky Dec 09 '19 at 16:59