Working with New and Edit Workflows in React
Now that we have our edit functionality working properly, it's time to connect the parent component with our form component, and what we're gonna do is build out two different workflows.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So we're going to give the ability for our form to be able to have one workflow if it is a new form submission, and it's gonna have a different workflow if it is a edit submission. Now we've already done that from an API perspective, but now we have to wire this up in the application itself, so let's get started on that.

The way we're gonna start out is by going into our FormSubmission in the portfolio form component, so we're gonna come down to where it says handleSubmit, and right now the reason why if you go and you hit Submit in the form right now, it'll create a new record is because it is calling this method, this handleSuccessfulFormSubmission method. And this is fine, this works perfectly if it is a new record. But what we need to do is to be able to split this behavior off if it happens to be an edit type of submission.

We're also gonna rename this method because we need this to say handleNewFormSubmission because we're going to build out a function for handling an edit submission. So let's do that first, just to make sure that we have our naming in a way that's nice and descriptive.

So I'm gonna say handleNewFormSubmission, and then we have to change this in a few different spots in the portfolio manager. So instead of handleSuccessfulFormSubmission, it's gonna say handleNew and then this is also going to be the name of the method.

portfolio-manager.js

render() {
  return (
    <div className="portfolio-manager-wrapper">
      <div className="left-column">
        <PortfolioForm
          handleNewFormSubmission={this.handleNewFormSubmission}
          handleFormSubmissionError={this.handleFormSubmissionError}
          clearPortfolioToEdit={this.clearPortfolioToEdit}
          portfolioToEdit={this.state.portfolioToEdit}
        />
      </div>

So we're passing this in as a prop and then let's go up top to actually change the function name itself. So handleSuccessfulFormSubmission now should say handleNewFormSubmission.

handleNewFormSubmission(portfolioItem) {
  this.setState({
    portfolioItems: [portfolioItem].concat(this.state.portfolioItems)
  });
}

And then in one last place inside of our constructor, now this is gonna say handleNewFormSubmission instead of successful and we're gonna bind that to this, so let's do all of that, hit save and so now this should work.

this.handleNewFormSubmission = this.handleNewFormSubmission.bind(this);
this.handleEditFormSubmission = this.handleEditFormSubmission.bind(this);
this.handleFormSubmissionError = this.handleFormSubmissionError.bind(this);

Let's hit save on the portfolio-form.js as well, it's always a good practice, anytime you make a refactor like this, even with something as simplistic as a name change, to go back and edit and update your actual code. Then you wanna make sure that you're actually testing it out, so let me hit refresh here.

The reason why I'm doing this is because you saw we just made four changes, and if we made one mistake, one typo or we forgot one spot of the application, then what could happen is we could assume that everything's working, we go and we add our dynamic behavior, and it's broken, and whenever that happens, it can be much more confusing to see where the break occurs, so that's why you make sure that you're always testing your application early and often.

So I'm going to create one with the name that says another one, gonna add a thumbnail just so we have an image here, and you don't have to add anything else, this is just to test it to make sure it's working. If I hit Save, everything's working like before. If I hit Refresh, the one that says another one is still there, so we're good to go, we're good to now actually finish the implementation.

So we now have the ability to properly have the right name, so we handle the NewFormSubmission. Now let's go and let's build a function for handling the editFormSubmission. So I'm gonna duplicate this line inside of the portfolio manager, but instead of it saying new, I'm just gonna have it say edit, just so the naming is very similar. But it's clear that this is happening only for the editing process.

And in fact, I'm gonna put this right next to the NewFormSubmission, just to make it easier to find. So I'm gonna say handleEditFormSubmission and what we're gonna have this do is it's not gonna take in any arguments, and inside of here, all we're gonna do is we're just going to call the getPortfolioItems function.

Now the reason why I'm doing this is because after we've edited the view, all we wanna do is have the system go through and repopulate all of the data because that's going to mimic exactly what happened, and we'll make sure that we're always working with the latest version of the data.

An alternative approach would be for us to iterate through the collection of portfolio items. And then if we find the record with the ID, then we simply swap them out and that would be another way of doing it but for this use case, I think it's perfectly fine to just hit the API one more time and make sure we're working with the latest version of the data.

So let me just go and make sure that I have the correct name for the getPortfolioItems and yes, I do, it's right here. And so we're going to just call this.getPortfolioItems, it doesn't take in any arguments, hit save and we're good to go.

portfolio-manager.js

handleEditFormSubmission() {
  this.getPortfolioItems();
}

Now we simply need to pass in handleEditFormSubmission as a prop to the Portfolio Form, and I'll put it right in front of or actually right after the handleNewFormSubmission. So we want to say =this.handleEditFormSubmission in curly brackets and after we've done that, now we can actually work with it here in the portfolio-form.js.

<PortfolioForm
  handleNewFormSubmission={this.handleNewFormSubmission}
  handleEditFormSubmission={this.handleEditFormSubmission}
  handleFormSubmissionError={this.handleFormSubmissionError}
  clearPortfolioToEdit={this.clearPortfolioToEdit}
  portfolioToEdit={this.state.portfolioToEdit}
/>

Now we need to know exactly when we want to call this edit process versus the handleNew and that's what we're gonna use our new condition of edit mode for. So what I can do inside of the response, and once again we're inside of handleSubmit here, is I can say if this.state.editMode and we can just say if that, we don't have to say if true 'cause remember this is the same thing as saying triple equals true.

We're just gonna say if this.state is in editMode, then what we're gonna do is call this.props.handleEditFormSubmission just like that, we don't have to pass in any arguments and then we'll say else and we'll say this.props.handleNewFormSubmission, and that is all that we need to do there. So this is gonna be our dynamic behavior. If we're in editMode, then we know that this is the workflow we're gonna call this handleEditFormSubmission and if not, we know that we're creating a new record.

.then(response => {
  if (this.state.editMode) {
    this.props.handleEditFormSubmission();
  } else {
    this.props.handleNewFormSubmission(response.data.portfolio_item);
  }

Now the last thing we need to do is to update our base state, we need to make sure that we're resetting it back to the correct apiUrl, to the correct action, and that's gonna get us back to where we want if a new record is gonna be submitted and then make sure we don't have any typos or anything, you can come all the way up to the constructor here and I'm simply going to grab editMode apiUrl and apiAction and then come down back into the handleSubmit, add a comma after logo and then paste it in, and that should be all that you need to do.

portfolio-form.js

this.setState({
  name: "",
  description: "",
  category: "eCommerce",
  position: "",
  url: "",
  thumb_image: "",
  banner_image: "",
  logo: "",
  editMode: false,
  apiUrl: "https://jordan.devcamp.space/portfolio/portfolio_items",
  apiAction: "post"
});

Okay, so we made a lot of changes, let's test this out and see if it's all working. I'm gonna hit Refresh and if I click on say this testing edit process here, all the data is populated and now I'm going to say testing again and when I hit Save here, this should automatically update what we have here without a page refresh.

So I'm gonna click Save and it looks like that worked perfectly, yes, so this is doing exactly what we want it to do.

large

large

So let's kinda take a little review on this 'cause I know we made quite a few changes. So the first thing we did is we created the handleEditFormSubmission function here and all that does is it resets all of our data, it calls the getPortfolioItems function, it brings in all of those records, and it populates our state for the portfolio manager.

That is only called inside of handleSubmit. So inside of handleSubmit, what we're doing is we're saying when the response comes back, I want you to check and see are we in edit mode or not? If we are, then I want to call the handleEditFormSubmission function and that's going to then do what we just walked through, it's going to go out to the API, it's gonna pull down all the portfolio items and it's gonna update state.

If not, then I want you to use just the standard handleNewFormSubmission function, we're gonna pass in that record and then the other workflow where all we do is we take that portfolio item that got returned to us and we're just going to stack that on top of all of the other ones, just like we've done up to this point.

Then lastly, we're going to return to a base state where we're gonna say editMode now is false, we're going to update the apiUrl and then the apiAction. So great job if you went through that, we now have a fully functional edit workflow and we're now using the form for multiple purposes.

We can share the majority of the functionality for creating records and for updating them which is the best process and that's really a best practice from a developer perspective.

So now that we have that, now let's walk through in the next few guides how we can work with images, how we can have images populated if there are already images for a record when we click Edit, how we can delete those and then how we can update them. So we're gonna spend a few guides going through that, so I'm looking forward to that.

Resources