I'm working on a POST request from React to Ruby on Rails backend; I tested the endpoint using Postman with the bellow data in JSON format:
{
"amount": 2,
"name": "Cheese and Loroco",
"price": "1.55"
}
And it worked(status 200); now, from React my JSON request looks like this:
{"ordertemp":[{"name":"Cheese and Loroco","amount":1,"price":"1.25"}]}
And I'm obtaining a status 400.
So the code that I'm using to generate the request is the bellow:
await fetch("http://localhost:3000/ordertemps", {
method: 'POST',
BODY: JSON.stringify({
//user: userData,
ordertemp: cartCtx.items,
}),
});
About my backend, I'm obtaining this otuput:
My controller sourcecode looks like this:
class OrdertempsController < ApplicationController
#GET /ordertemps
def index
#ordertemps = Ordertemp.all
render json: #ordertemps
end
#GET /ordertemp/:id
def show
#ordertemp = Ordertemp.find(params[:id])
render json: #ordertemp
end
#POST /ordertemps
def create
#ordertemp = Ordertemp.new(ordertemp_params)
if #ordertemp.save
render json: #ordertemp
else
render error: { error: 'Unable to create an order'}, status: 400
end
end
#PUT /ordertemps/:id
def update
#ordertemp = Ordertemp.find(params[:id])
if #ordertemp
#ordertemp.update(ordertemp_params)
render json: { message: 'Order successfully updated.'}, status: 200
else
render json: { error: 'Unable to update the order.', status: 400}
end
end
#DELETE /ordertemps/:id
def destroy
#ordertemp = Ordertemp.find(params[:id])
if #ordertemp
#ordertemp.destroy
render json: { message: 'Order successfully deleted.'}, status: 200
else
render json: { error: 'Unable to delete Order.'}, status: 400
end
end
private
def ordertemp_params
#params.require(:ordertemp).permit( :clientName, :clientId, :amount, :mealid, :name, :price)
params.require(:ordertemp).permit(:amount, :name, :price)
end
end
So, I would like to request your help with the next questions:
should I get rid off the "ordertemp" at the beginning of my JSON from React? in the case yes, how can I accomplish it?
what else am I forgetting to get a status 200 instead of 400?
Thanks a lot
I don't do ruby, but with postman you are sending this
{
"amount": 2,
"name": "Cheese and Loroco",
"price": "1.55"
}
whereas on react you are sending this:
{"ordertemp":[{"name":"Cheese and Loroco","amount":1,"price":"1.25"}]}
They are not the same, so start with the same use case and see if it works.
Also, BODY should be body and you could add headers like in the fetch example
I noticed in your controler that Ordertemp is the a capitalized letter (I don't know if it matters)
Related
I'm trying to get user data to save to my Rails DB for user info through a sign up form on a React front end. I've got my route and controller written properly (at least I think) and the fetch request below but I keep getting a 500 internal error through on submit. Please let me know what I'm missing, any help would be greatly appreciated!
My route:
resources :users, only: [:show, :create]
My create action in UsersController:
def create
user = User.create!(user_params)
if user.valid?
session[:user_id] = user.id # remembering who our user is
render json: user, status: :ok
else
render json: {error: user.errors.messages}
end
end
and lastly my fetch request from the Signup.js component on the React frontend, where I'm getting the error on the line that has 'fetch'
fetch(`/users`,{
method:'POST',
headers:{'Content-Type': 'application/json'},
body:JSON.stringify(user)
})
.then(res => {
if(res.ok){
res.json().then(user => {
history.push(`/users/${user.id}`)
})
This might only be part of your problem, but first creating, then asking for validity is backwards.
Do something like this instead:
def create
user = User.new(user_params)
if user.save # <-- will return false if the save fails
user.reload
session[:user_id] = user.id # remembering who our user is
render json: user, status: :ok
else
render json: {error: user.errors.messages}
end
end
If you really want to check validity explicitly:
def create
user = User.new(user_params)
if user.valid? # <-- will check validity
user.save
user.reload
session[:user_id] = user.id # remembering who our user is
render json: user, status: :ok
else
render json: {error: user.errors.messages}
end
end
My guess is your error might be coming from the fact that your user variable doesn't actually have an ID yet. You need to save the record, then refresh it to get an ID.
I am getting this error trying to update a card for my application. Here's a look at the rails server log. The ID is coming back "nil". I can't figure out why. Here is the PATCH update block of code:
function handleEdit(e) {
e.preventDefault()
fetch(`/items/${item.id}`,{
method: "PATCH",
body: JSON.stringify({
item: id,
bottle: bottle,
size: size,
count: count,
}),
headers: {
"Content-Type": "application/json",
},
})
.then(res=>res.json())
.then((updatedItem)=>setItem(updatedItem))
}
Here are all the routes:
resources :items, only: [:index,:show,:update]
get '/me', to: 'couriers#show'
get "/home", to: 'couriers#show'
get '/courier', to: 'couriers#show'
get '/items', to: 'items#index'
get 'items/:id', to: 'items#update'
get '/items/:id', to: 'items#show'
patch '/items/:id', to: 'items#update'
post '/login', to: 'sessions#create'
post '/signupform', to: 'couriers#create'
delete '/logout', to: 'sessions#destroy'
Here is the error log:
Started PATCH "/items/undefined" for 127.0.0.1 at 2022-08-01 19:27:47 -0400
Processing by ItemsController#update as */*
Parameters: {"item"=>nil, "bottle"=>"Glass", "size"=>"400", "count"=>"4", "id"=>"undefined"}
Item Load (0.2ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 LIMIT $2 [["id", nil], ["LIMIT", 1]]
↳ app/controllers/items_controller.rb:19:in `update'
Completed 404 Not Found in 4ms (Views: 0.2ms | ActiveRecord: 0.9ms | Allocations: 1234)
Here is the code in the ItemsController:
class ItemsController < ApplicationController
skip_before_action :authorize, except: :index
def index
items = Item.all
render json: items, status: :ok
end
def show
item=Item.find_by(id:session[:id])
if item
render json: item
else
render json: {error: 'Not Found'}, status: :not_found
end
end
def update
item = Item.find_by(id:params[:id])
if item
item.update(item_params)
render json: item
else
render json: { error: "Item not found" }, status: :not_found
end
end
private
def item_params
params.permit(:id,:item,:bottle, :size, :count)
end
end
If anyone has an idea or resolution, please share. I'm sure it's something I may be doing wrong, so anything helps.
Not super sure how React apps work, but should that ${items.id} in the patch code be ${item.id} (singular)?
Out of curiosity, where is the item (or items) var actually set? Again, I'm not familiar with React, but that's the source of the 'undefined' text being passed to the controller. Whatever is rendered in the ${ } section is undefined. It is being turned into the literal text 'undefined' and that is being sent to your controller.
I'm working on posting data from a React Form to a Ruby on Rails API, about the React part, if just send the first item from an array using this code:
const submitOrderHandler = async (userData) => {
setIsSubmitting(true);
await fetch("http://localhost:3000/ordertemps", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(cartCtx.items[0]),//please include user: userData
});
setIsSubmitting(false);
setDidSubmit(true);
cartCtx.clearCart();
};
The Ruby on Rails API manage it and store it in the table, this is the output:
However, I need to store all the data selected by the user, so, to accomplish this task I updated my code like this:
const submitOrderHandler = async (userData) => {
const dataSelected = JSON.stringify(cartCtx.items);
console.log(dataSelected);
setIsSubmitting(true);
await fetch("http://localhost:3000/ordertemps", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(cartCtx.items),//please include user: userData
});
setIsSubmitting(false);
setDidSubmit(true);
cartCtx.clearCart();
};
The problem is I'm getting a 400 Status, so this is how the data looks from the FrontEnd:
This is the output from the Ruby on Rails Endpoint:
the source code of the Controller in charge to manage and store the data is this:
#POST /ordertemps
def create
#ordertemp = Ordertemp.new(ordertemp_params)
if #ordertemp.save
render json: #ordertemp
else
render error: { error: 'Unable to create an order'}, status: 400
end
end
private
def ordertemp_params
#params.require(:ordertemp).permit( :clientName, :clientId, :amount, :mealid, :name, :price)
params.require(:ordertemp).permit(:name, :amount, :price)
end
So, I'm assuming these facts:
the data is properly formatted from the FrontEnd.
For some reason my Ruby on Rails'Controller can't manage more than one element sent by the front end.
My question is: what am I missing in my controller to store all the data sent by the FrontEnd?
Thanks a lot for your comments
Update your controller code as below:
#POST /ordertemps
def create
begin
params['_json'].each do |ordertemp_params|
#ordertemp = Ordertemp.new(ordertemp_params)
#ordertemp.save
end
head :no_content
rescue => e
render json: { error: unable to create orders }, status: 400
end
end
Hope this will help you.
I have a rails 5.2 API that currently creates and authenticates users (tested in Postman). However, I have added another model called Stories and when I attempt to create a new Story, a story is created but only the id attribute is saved.
Here is my StoriesController:
class StoriesController < ApplicationController
before_action :set_story, only: [:show, :update, :destroy]
# GET /stories
def index
#stories = Story.all
render json: #stories
end
# POST /stories
def create
#story = Story.new(story_params)
if #story.save
render json: #story, status: :created
else
render json: { errors: #story.errors.full_messages },
status: :unprocessable_entity
end
end
# GET /stories/:id
def show
render json: #story
end
# PUT /stories/:id
def update
#story.update(story_params)
head :no_content
end
# DELETE /stories/:id
def destroy
#story.destroy
head :no_content
end
private
def story_params
# whitelist params
params.permit(:title, :category, :summary)
end
def set_story
#story = Story.find(params[:id])
end
end
Here is the request in Postman:
Here is the output in Postman:
I thought this was a params issue, but that does not seem to be it.
man there is an extra opening bracket on your post payload on line 3.
The right json payload is.:
{
"story": {
"title": "Spiderman"
"category": "Superhero"
"summary": "new spiderguy ftw"
}
}
I think there is a issue with your story_params method. The Story attributes "tittle", "category" and "summary" are nested in "story".
You can try this:
params.require(:story).permit(:title, :category, :summary)
I created an API using the rails-api gem and I have an client app based on angular in which I use ng-resource.
I do think that the request I send to my API should be more like {post=>{"kind"=>"GGG"}} and not {"kind"=>"GGG"} of I have to find a way for my api to work with the request I send now. For now I'm stuck with 400 Bad Request errors and I can't find out how to fix it.
Here is my rails controller :
class PostsController < ApplicationController
# GET /posts
# GET /posts.json
skip_before_filter :verify_authenticity_token, :only => [:update, :create]
def index
#posts = Post.all
render json: #posts
end
# GET /posts/1
# GET /posts/1.json
def show
#post = Post.find(params[:id])
render json: #post
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
if #post.save
render json: #post, status: :created, location: #post
else
render json: #post.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
#post = Post.find(params[:id])
if #post.update(params[:post])
head :no_content
else
render json: #post.errors, status: :unprocessable_entity
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post = Post.find(params[:id])
#post.destroy
head :no_content
end
private
def post_params
params.require(:post).permit(:post, :kind)
end
end
Here is my angular controller :
$scope.postData = {};
$scope.newPost = function() {
console.log($scope.postData);
var post = new Post($scope.postData);
post.$save($scope.postData);
}
Here is my angular factory :
.factory('Post', function($resource) {
return $resource('http://localhost:3000/posts');
})
In my logs I have :
Started POST "/posts?kind=GGG" for 127.0.0.1 at 2014-05-26 18:21:21 +0200
Processing by PostsController#create as HTML
Parameters: {"kind"=>"GGG"}
Completed 400 Bad Request in 2ms
ActionController::ParameterMissing (param is missing or the value is empty: post):
app/controllers/posts_controller.rb:55:in `post_params'
app/controllers/posts_controller.rb:23:in `create'
-
Change the following code:
def post_params
params.require(:post).permit(:post, :kind)
end
To be:
def post_params
params.permit(:post, :kind)
end
And you problem will be fixed.