Use fetch to pass variable in rails - ruby-on-rails

I am creating an app in Rails with Reactjs. I want to pass the value of input field to the controller as a variable so that I can use that variable in def create. How can I do that with fetch?

Use fetch's POST request to your API backend endpoint of your :create method. Make sure that you include your variables in a params payload when POSTing.
Then in your controller, you can access your variables through params
EDIT:
From the fetch api docs example in using POST (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
async function postData(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
return response.json();
}
postData('/your/api/endpoint', { data: 'yourData' }).then(res=> { console.log(res) });
Then in your controller, access { data: 'yourData' } through params like so:
def create
#data = params[:data]
// Do what you want with #data here
end
It's also best to whitelist your params first before using them in your controller.

Related

How to combine two actions together

I have two API calls, one is an input for the second, I'm defining them as two actions now, but I wonder if I can merge them together in one action, I couldn't find that in the documentation, is that possible? and how?
My case is that I have an action that creates an invoice and returns back its id, the id then is being passed to another API to confirm that invoice and returns back a pdf.
Should I encapsulate the APIs from the back-end? or does it work if I called the second API inside the "then" method:
const options = {
url: 'https://my.fastbill.com/api/1.0/api.php',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
params: {
},
body: {
'SERVICE': 'invoice.complete',
'DATA' : {
'INVOICE_ID': bundle.inputData.INVOICE_ID
}
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = response.json;
// Call the second API here
return results;
});
Yes you can use a hidden trigger to call the first action and pass the input into a dynamic dropdown , then use it along the other inputs to submit the final action.
https://platform.zapier.com/cli_tutorials/dynamic-dropdowns

Missing parameters in Rails Controller when using multipart/form-data in React

I am using Rails and React with Axios to create a record. In my React app I collect all the data and put it inside of FormData like this:
const createVtc = () => {
let data = new FormData()
data.append('image', vtcImageToSend)
data.append('name', vtcName)
data.append('description', vtcDescription)
data.append('main_color', vtcColor)
data.append('minimum_age_to_join', vtcMinimumAge)
axios.post(`${ROOT_API}/v1/vtcs/create`, data, {
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'multipart/form-data'
}
}).then(res => {
console.log(res.data);
history.push('/dashboard')
}).catch(err => {
console.log(err);
})
};
This contains all the necessary data in order to create a record.
This is the Rails controller responsible for creating it:
def create
vtc = Vtc.new(vtc_params)
# other code is not important
end
And this is vtc_params private function:
def vtc_params
params.require(:vtc).permit(:id, :name, :description, :minimum_age_to_join, :main_color, :image)
end
Pretty standard stuff. It worked until I had to implement picture upload which made me switch to FormData upload and since then Rails throws this error:
ActionController::ParameterMissing in V1::VtcsController#create
param is missing or the value is empty: vtc
I can assume what's the problem but I don't know how to fix it. Before FormData I used to send it like this:
// other stuff
axios.post(`${ROOT_API}/v1/vtcs/create`, {
"vtc": {
"name": vtcName,
// etc.
}
}, {
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'multipart/form-data'
}
})
// other stuff
All of the data was inside of "vtc" object but now it's just data variable. I tried adding {"vtc": data} as Axios data which not surprisingly didn't work.
Just wrap your data variable in an object with the key vtc:
axios.post(`${ROOT_API}/v1/vtcs/create`, {vtc: data}, {
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'multipart/form-data'
}

Redirect from Rails controller after Angular POST

I have a normal Rails app (no SPA) and on one page only I'm using Angular.
At the end I'm sending a POST to the server with the form data (and it is working) and as the final step of the POST I'd like to redirect to another page.
Rails controller is like this:
def save
data = params[:data]
respond_to do |format|
format.js { render :js => "window.location.href = '/products';" }
end
end
But nothing is happening.
My Angular post is simple:
app.service('httpService', ['$http', function($http) {
this.post = function(data) {
$http({
method : 'POST',
url : '/cart/save',
data : { data: data },
headers : {'Content-Type': 'application/json'}
});
};
}]);
Calling service just like this, no promises:
this.save = function(ids) {
httpService.post(ids);
};
Any ideas? Thanks.
EDIT:
I have tried also change the mime-type to 'application/javascript', but no success:
app.service('httpService', ['$http', function($http) {
this.post = function(data) {
$http({
method : 'POST',
url : '/cart/save',
data : { data: data },
headers : {'Content-Type': 'application/javascript'}
});
};
}]);
Ok, so the problem was that the $http is sending an asynchronous request, thus the page cannot be redirected.
The solution was to send jQuery synchronous $.ajax(..., async: false);.

AngularJS sends nil parameters to API

I created a basic API with Ruby on Rails. Whenever I try to send data from a form in AngularJS, I get this message in the Rails Server:
Parameters: {"{\"content\":\"message\"}"=>nil}
So, it's creating null records in the DB.
This is the controller in AngularJS to send the data:
app.controller('postController', function($scope, $http) {
// create a blank object to handle form data.
$scope.message = {};
// calling submit function.
$scope.submitForm = function() {
$http({
method : 'POST',
url : 'http://localhost:3000/api/v1/messages',
data : $scope.message, //forms user object
headers : {'Content-Type': 'application/x-www-form-urlencoded'}
})
.success(function(data) { ... }
});
};
});
You need to serialize the data when you send as x-www-form-urlencoded
Example copied from docs
.controller(function($http, $httpParamSerializerJQLike) {
//...
$http({
url: myUrl,
method: 'POST',
data: $httpParamSerializerJQLike(myData),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
});
Or use the defaults of $http which sends JSON in request body as application/json:
$http.post(myurl, data).then(...;
change this line:
headers : {'Content-Type': 'application/x-www-form-urlencoded'}
to:
headers : {'Content-Type': 'application/json'}
Also encode to Json if it isnt like this:
data : angular.toJson($scope.message), //forms user object
This way you will send the correct JSON formatted data to API, make sure your API accepts Json encoded data just in case.

Parameters vs JSON strings while designing an API with Rails for use with AngularJS

I am building an API to receive POST data and return JSON in Ruby on Rails 3. I am submitting the data using the angularjs $http object.
var post_data = {
content: $scope.post_content,
authentication_token: csrf
};
$http({
url: feed_endpoint,
method: "POST",
'Content-Type': 'application/json',
params: post_data
}).success(function(post_data, status, headers, config) {
}).error(function(post_data, status, headers, config) {
$scope.status = status;
});
}
The escaping of quotes etc. works well with this method where I was having issues with the JSON being created incorrectly while just passing a js data object(hash) to the $http.data object.
I am looking for input on the merits of doing it either way.
Thanks.
Try using $http.post, this form works for me.
$http.post(feed_endpoint, post_data, {"Authorization": ""})
.success(function(response) {...}

Resources