0

My app is built with ruby on rails on the backend, and react.js on the front end.

I can see in my rails console that I get the updated information from my http.patch request in rails, and it is received in rails, and now I am trying to adjust the update controller action to be able to redirect to the /donations page.

My routes for donations are as follows:

Routes

I am trying to figure out how I can redirect the routes so that when the PATCH occurs, it will send the user to the list of all donations, instead of staying on the /edit page which is what it is currently doing. My current update action is:

    def update
      if @donation.update(donation_params)
        render json: @donation
      else
        render json: @donation.errors, status: :unprocessable_entity
      end
    end

I know this will not redirect at all, but I have tried to redirect_to donations_path and it will not work still. I tried to update the patch in the routes, to route to donations#index, but that doesn't work either... I am almost certain it is something to do with the update action, and/or, routes.rb, but this is my first time trying to patch an item and redirect - seems to be more complicated then I have ran into before... anyone know any suggestions to try?

Currently my routes for donations are back to square one:

    resources :donations, module: 'team'

looking for any suggestions on how to do something like this. Appreciate it in advance.

I expect that after I click save on my form, it passes the donation json back to rails, and then continues to redirect using rails routing, through the update action.

UPDATE: Added code to show the UseEffect, and handleSubmit functions, as well as the onClick call in the return to give more context to the client side operations.

    import React, { useEffect, useState } from "react";
    import PropTypes from "prop-types";
    import { HTTP } from "../../api/resources";

    export default function DonationsEdit({donation: donationProps}) {
      const [donation, setDonation] = useState(null);
      const [saving, setSaving] = useState(false);
  
      useEffect(() => {
        if (!donation) {
          setDonation({
            ...donationProps,
            unit_cost: parseFloat(donationProps.unit_cost).toFixed(2)
          });
        }
      }, [donation, donationProps]);


    const handleSubmit = () => {
      setSaving(true)
      HTTP.patch(`/donations/${donation.id}`, {
      donation: donation
    }).then(response => {
      Alert.show("notice", "Donation Item Saved!");
      setDonation(response.data);
      setSaving(false);
    }).catch(e => {
      Alert.show("error", "Could not save. Try again or refresh.");
      setSaving(false);
    })
  }

  return (
    <React.Fragment>
        <div>
            <button onClick={handleSubmit} name="button" className="btn btn-primary">
              {saving && <i className="fa fa-spinner-third fa-spin mr-2"></i>}
              Save
            </button>
          </div>
        </div>
Creider9
  • 1
  • 1
  • When you say you tried `redirect_to donations_path` and it "didn't work" what happened? Error? Nothing? Can you post the console logs when you tried that? – Beartech Dec 06 '22 at 08:04
  • There was an error saying it can’t redirect to /donations/undefined, so it clearly doesn’t know when donation.id is being referred to … I tried passing it in as a variable to donations_path(@donations.id) but the problem still existed – Creider9 Dec 06 '22 at 08:23
  • I also tried redirect_to donation_path and the problem still persisted – Creider9 Dec 06 '22 at 08:28
  • You're thinking about this completely wrong. The server should either give the client a response body (JSON) or a redirect status code (300-308) with a `LOCATION` header. If you send both the client would redirect before it even actually does anything with the request body. What you want is probally just to do a client side redirect (`window.location = "/somewhere_else"`) or a simple transformation. – max Dec 06 '22 at 09:16
  • Usually in a API you respond to a successful PATCH request with `200 - OK` or `204 - NO CONTENT`. You rarely need to send JSON back as the client already knows what it updated and if it needs to refresh the data it can get it via `GET /thing/:id`. I think part of your problem here is that you're still thinking in terms of classical apps where the server side is responsible for steering the user around the application. In a SPA that responsibity is on the client side and the server is just responsible for delivering data. – max Dec 06 '22 at 09:24
  • Additionally sending a redirect in response to an XHR request doesn't cause the browser to redirect the window. It will either just do nothing or cause a new XHR request if you're using the options to follow redirects. This question won't be answerable without the relevant React code which is where you should actually be handling this. – max Dec 06 '22 at 09:37
  • Got it - thanks Max. I was thinking about doing it on the client side but thought it would be easier if I did it with rails routes. I will revision this with an attempt at the client side redirect and post the react code for further help if needed. – Creider9 Dec 06 '22 at 16:31
  • I added a snippet of the react code to the original post. – Creider9 Dec 06 '22 at 17:08

1 Answers1

0

Thank you Max, I did the redirect on the client side and it worked using:

const handleSubmit = () => {
  setSaving(true)
  HTTP.patch(`/donations/${donation.id}`, {
    donation: donation
  }).then(response => {
    Alert.show("notice", "Donation Item Saved!");
    setDonation(response.data);
    setSaving(false);
    setTimeout(function() { window.location.href= '/donations';}, 1500);
  }).catch(e => {
    Alert.show("error", "Could not save. Try again or refresh.");
    setSaving(false);
  })
}
Creider9
  • 1
  • 1