how to update the url after saving a post

Viewed 329

I'm building an editor which can save and update post. The problem I'm facing is that after saving the post for the first time, I get a snippetId from the server which I want to show in the url immediately or else my route is still http://localhost:8000/editor and if I hit save button again then it saves a duplicate copy with a different id. I want the editor url to be something like http://localhost:8000/editor/123 after saving for the first time so that when I hit the save button again then it updates the post instead of saving a duplicate copy with a different id. I was wondering how to tackle this problem? can someone help me find a solution for this problem

codesandbox

editor.js

import React, { Component } from "react";
import { connect } from "react-redux";
import { savePost, retrievePost } from "./actions/posts";

class Editor extends Component {
  constructor(props) {
    super(props);

    this.state = {
      title: "",
      enteredText: ""
    };
    this.commonChange = this.commonChange.bind(this);
  }
  commonChange(event) {
    this.setState({
      [event.target.name]: event.target.value
    });
  }
  componentDidMount() {
    //Load the snippet
    retrievePost(this.props.match.params.snippetId);
  }

  // Save Snippet
  performSave = snippets => {
    console.log("save function clicked");
    const { enteredText, title } = this.state;
    this.props.savePost({
      snippetId: this.props.match.params.snippetId, //if the url doesn't change then this also doesn't change so I get duplicate copies 
      snippetDescription: enteredText,
      snippetTitle: title
    });
  };
  render() {
    return (
      <>
        <input
          type="text"
          id="titletext"
          placeholder="Enter title here"
          limit-to="64"
          className="inptxt"
          name="title"
          onChange={this.commonChange}
        />
        <button className="btn savebtn" onClick={this.performSave}>
          Save Snippet
          <i className="fas fa-save" />
        </button>

        <textarea name="enteredText" onChange={this.commonChange} />
      </>
    );
  }
}

const mapStateToProps = state => ({
  snippets: state.snippets
});

export default connect(
  mapStateToProps,
  { savePost, retrievePost }
)(Editor);

action.js

import { SAVE_POST, UPDATE_POST, RETRIEVE_POST, HOME_LOADED } from "./types";
import axios from "axios";
export const savePost = ({
  snippetId,
  snippetDescription,
  snippetTitle
}) => async dispatch => {
  const config = {
    headers: {
      "Content-Type": "application/json"
    }
  };

  let snippetData = {
    title: snippetTitle,
    snippetDescription: snippetDescription
  };
  // --------------------------------------
  console.log("in savePost action");
  try {
    if (snippetId == null) {
      const res = await axios.post("/api/savesnippets", snippetData, config);
      snippetData.snippetId = res.data; //cause I only get snippetId from the server
      dispatch({
        type: SAVE_POST,
        payload: snippetData
      });
    } else {
      //add snippetId here for update use only --------------------------------------
      await axios.post(
        "/api/update",
        JSON.stringify({ ...snippetData, snippetId }),
        config
      );
      // --------------------------------------
      dispatch({
        type: UPDATE_POST,
        payload: snippetData
      });
    }
  } catch (err) {
    console.log(err);
  }
};
1 Answers

You can history.push() from react-router for this purpose like:

history.push('/editor' + id_you_get_from_ajax_call);

And use it where you are getting the ajax response, so for every success you will get a new id_you_get_from_ajax_call and it will update the route.

and create a matching route for editor like:

<Route path="editor/:id" component={ YOUR_COMPONENT } />

React-router history.push() Reference

Related