No data in params on POST request - ruby-on-rails

Currently I have a problem with an Angular2 and RoR5 API. I'm trying to save an object to the API Server, but this doesn't work.
Here is my Angular2 Code for the service:
createFrame(frameData) {
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
let body = JSON.stringify({frame: frameData});
return this.http.post(this.frameURL, body, headers).map((res: Response) => res.json());
}
The request is made by my browser and I can see the JSON Data:
But RoR is not able to get the POST Data.
[1] pry(#<Api::V1::FramesController>)> params
=> <ActionController::Parameters {"format"=>:json, "controller"=>"api/v1/frames", "action"=>"create"} permitted: false>
[2] pry(#<Api::V1::FramesController>)>
Can someone tell me, what's wrong?

In your case, you set the content type for form data and you send some content with the JSON format.
Either you use send form data or JSON content.
Form data
createFrame(frameData) {
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
let form = new URLSearchParams();
form.set('param1', 'some value');
let body = form.toString();
return this.http.post(this.frameURL, body, headers).map((res: Response) => res.json());
}
JSON data
createFrame(frameData) {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
let form = new URLSearchParams();
form.set('param1', 'some value');
let body = form.toString();
return this.http.post(this.frameURL, body, headers).map((res: Response) => res.json());
}

The problem might be related to CORS (Cross Origin Resource Sharing)
Thy to enable in your application -->
Enabling cors Rails5
Good luck

Related

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'
}

Zapier API Configuration: send form-data instead of json request body

I am setting up a Zap for our application in Zapier.
However, I've run into some trouble having the Zap pass over the data in the correct format.
By default it appears Zapier passes the data as json request body, but our backend only accepts form-data.
Is it possible to configure the Zap to send over form-data instead?
In the code below, I've tried to send the data as both params and body, but my backend doesn't any of it as form-data:
const options = {
url: '${URL}',
method: 'POST',
headers: {
'Authorization': ${token},
'Content-Type': 'application/json',
'Accept': 'application/json'
},
params: {
'phone': bundle.inputData.phone,
'email': bundle.inputData.email,
'dialog': bundle.inputData.dialog,
'name': bundle.inputData.name
},
body: {
'name': bundle.inputData.name,
'email': bundle.inputData.email,
'phone': bundle.inputData.phone,
'dialog': bundle.inputData.dialog
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = z.JSON.parse(response.content);
// You can do any parsing you need for results here before returning them
return results;
});
Any input is greatly appreciated!
I fixed it by replacing 'Content-Type': 'application/json' with 'Content-Type': 'application/x-www-form-urlencoded'.

Observable with POST call in Angular2

I am using Angular2 in my application, And I saw advantages of using Observable while calling http calls. But somehow I am not able to make call when I am using Observable for POST requests, But it's working while GET request. If I use subscribe method, then POST is working.
Below is my code,
using Observable,
AddBreakoutsManually(breakoutUploads: Uploads): Observable<boolean> {
console.log("Data = ", JSON.stringify(breakoutUploads));
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post("/breakout/InsertUploads", JSON.stringify(breakoutUploads), options)
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json().error || 'Server error'));
}
Using subscribe,
Adding(breakoutUploads: Uploads) {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http
.post('/breakout/InsertUploads', JSON.stringify(breakoutUploads), options)
.subscribe(data => {
alert('ok');
}, error => {
console.log(error.json());
});
}
My API,
[HttpPost]
public bool InsertUploads([FromBody]BreakoutUpload breakoutUploads)
{
return true;
}
What mistake I am making while using observable in POST call ?
Not sure what I changed, But it starts working with below code,
AddBreakoutsManually(breakoutUploads: Uploads): Observable<string> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(Configuration.Url_AddBreakoutsManually, JSON.stringify(breakoutUploads), options) // ...using post request
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json().error || 'Server error'));
}

Angular 2 urlencoded in http post

I try to consume a service via post whit angular2. This my code:
var m_dataRequest = this.buildLoginUserPasswordRequest(password, key);
let headers = new Headers({
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'es-ES,es;q=0.8,en;q=0.6',
'Content-Type': 'application/x-www-form-urlencoded',
});
let options = new RequestOptions({ headers: headers });
let body = new URLSearchParams();
body.set("message", JSON.stringify(m_dataRequest));
body.set("webService", "authService");
return this.http
.post(this.Url, body.toString(), options)
.toPromise()
.then(this.extractData)
.catch(this.handleError);
private buildLoginUserPasswordRequest(password:string, key:string): any {
var m_dataRequest = {
"ser:nativeAppAuth": {
"-xmlns:ser": "http://services.mobileappbc.ws.todo1.com/",
"password": this.utilService.buidRSAPass(password, t1Assertion),
"key": key,
"deviceInfo": this.utilService.getDeviceInfo()
}
};
return m_dataRequest;
}
The Content-type is application/x-www-form-urlencoded because the backend need the info of this way.
My problem is the character ":" is not convert to equivalent urlencoded %3A+.
this cause a problem in my backend service.
any Suggestion for solve this?
Thanks!
Json.stringify does not uri encode data because it can handle it.
You need to use uriencode()
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

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.

Resources