1

this is my component:

import { Field, FieldArray, Form, Formik } from "formik";
import { connect } from "react-redux";

import { withRouter } from "react-router";
import { updateEpisode } from "../../ducks/episodes/actions";
const AddActorToMovie = (
  { history, updateEpisode, episode, characters },
  props
) => {
  const handleSubmit = (values) => {
    updateEpisode(values);
    history.push("/episodes");
  };
  console.log("halo", episode);
  return (
    <div>
      {episode ? (
        <div>
          <h3>Add Main Character to episode</h3>
          <Formik
            initialValues={{
              id: episode.id,
              title: episode.title,
              release_date: episode.release_date,
              series: episode.series,
              img: episode.img,
              charactersList: episode.charactersList, // this would be an array
            }}
            onSubmit={(values) => handleSubmit(values)}
            enableReinitialize={true}
          >
            <Form>
              <Field name="charactersList" as="select">
                <option value=""> Brak informacji </option>
                {characters.map((char) => (
                  <option
                    key={char.id}
                    value={char.id}
                  >{`${char.name}`}</option>
                ))}
              </Field>
              <button type="submit">Zatwierdz</button>
            </Form>
          </Formik>
        </div>
      ) : (
        <div>Loading...</div>
      )}
    </div>
  );
};

const mapStateToProps = (state, props) => {
  return {
    episode: state.episodes.episodes
      ? state.episodes.episodes.find(
          (x) => String(x.id) === props.match.params.id
        )
      : null,
    characters: state.characters.characters,
  };
};

const mapDispatchToProps = {
  updateEpisode,
};

export default withRouter(
  connect(mapStateToProps, mapDispatchToProps)(AddActorToMovie)
);

What i would like to do, is instead of adding only one value = char.id to charactersList i woudl like to add multiple. So that charactersList woudl be an array and i could add as many characters i could and also if possible i could also delete some of them in this form, as im using my updateEpisode action so that im passing a updated object to my state. I know that probably i shoudl do it with FieldArray but i don't know how.

1 Answer 1

2

Personally i don't use <Field />, i prefer manual setFieldValue because it gives you more freedom. By using setFieldValue you can loop through the char.id and push them to the charactersList by getting prev value from 'value.charactersList' and set the new value with setFieldValue.

<Formik
  initialValues={{
    id: episode.id,
    title: episode.title,
    release_date: episode.release_date,
    series: episode.series,
    img: episode.img,
    charactersList: episode.charactersList, // this would be an array
  }}
  onSubmit={(values) => handleSubmit(values)}
  enableReinitialize={true}
>
  {
    ({ values, setFieldValue, handleSubmit }) => (
      <Form>
        <h3>Character List</h3>
        {
          characters.map((char) => (
            <button name={char.id} value={char.id} onclick={() => {
              const oldData = values.charactersList;
              if(!Array.isArray(oldData)) return;
              const isExist = oldData?.includes(char.id)
              if(isExist) {
                // filter out the char u want to delete
                const newData = oldData?.filter(i => i !== char.id)
                setFieldValue('characterList', newData)
                return;
              }
              const newData = oldData?.concat(char.id);
              setFieldValue('characterList', newData);
            }}>
              {char.name}
            </button>
          ))
        }
        
        <button type="submit" onclick={handleSubmit}>Zatwierdz</button>
      </Form>
    )
  }
</Formik>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/formik/dist/formik.umd.production.min.js"></script>

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

4 Comments

Ok, it did work. But do you know how i can manage it so you could not add character of same id twice?
i've updated code above, adding isExist
Thanks! But know i also wonder, how can i implement deleting? Is it possible to delete data using this form? Let's just say that if this character already exsist in array, i can click the button or any other button to remove him from the charactersList
you can filter out the when button with the same char id clicked, then feed back the data to the values using setFieldValues just like my last edit

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.