How to pass 3 argument to backend with `POST` request? - angular7

According to backend, I require to pass 3 argument through post request, this backend function is:
public ResponseModel Post([FromBody] CourseFileUpload item, string fileName, Stream fileToUpload)
now I am trying to pass the argument like this:
uploadFile(uploadData:ModelToFileSteam):Observable<ModelToFileSteam> {
const fileName = uploadData.fileName;
console.log('file name is', fileName);
const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Access-Control-Allow-Origin':'*' });
return this.http.post<ModelToFileSteam>(environment.baseUrl+`CourseFileUpload`, uploadData.fileToUpload, uploadData.fileName, uploadData.uploadStream)
.pipe(
map(data => {
return data;
} ),
catchError(this.handleError)
)
}
But getting error, not able to pass 3 arguments at all. what is the correct way to do this?
any one help me?

I will suggest wrapping all in a single object. And send it to backend.
Or just send uploadData
return this.http.post<ModelToFileSteam>(environment.baseUrl+`CourseFileUpload`, uploadData)
.pipe(
map(data => {
return data;
} ),
catchError(this.handleError)
)
And in the backend, you can get uploadDate like req.body.uploadData
To check you can console.log(uploadData.fileName);

its my working example
this.http.post<Customer>(this.base_url + 'v1/customers', client, this.getHeaders());
Where client is customer object and this.getHeaders() is:
getHeaders() {
return {
headers: new HttpHeaders({
'Content-Type': 'application/json; charset=utf-8',
})
};
}
Good luck!

Related

Getting 400 (Bad Request) on a POST request to Strapi

I am trying to post data to my Strapi project from a Flutter app.
I made sure that the permissions are enabled for unauthenticated users.
What is wrong with my request?
Future saveReview(usrReview, usrRating) async {
const endpoint = 'http://localhost:1337/api/reviews';
var url = Uri.parse(endpoint);
Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
};
var reviewObj = jsonEncode({
'review': usrReview,
'rating': usrRating,
});
var response = await http.post(
url,
headers: headers,
body: reviewObj,
);
print(response.statusCode);
}
The problem was that the structure of reviewObj was missing something. I had to include 'data' in it for it to work. Here is what the correct body should look like.
var reviewObj = jsonEncode({
'data': {
'review': usrReview,
'rating': usrRating,
}
});
I think this might fix you're problem! I recently ran into this same error a few days ago!
Basically you have to send the body of the POST request as a string.
Here's what it should look like!
Future saveReview(usrReview, usrRating) async {
const endpoint = 'http://localhost:1337/api/reviews';
var url = Uri.parse(endpoint);
Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
};
// Pass the JSON data as a whole string. Then the server should parse it
var reviewObj = '{"review": $usrReview, "rating": $usrRating}';
var response = await http.post(
url,
headers: headers,
body: reviewObj,
);
print(response.statusCode);
}
Give that a try and let me know if that works!

Reg: Angular API Return data with array index "value below was evaluated just now”

i am using Angular for front end. i am using the API request to bring languages and phrases. return data is pushed into declared array variable.
```public data = [];
constructor(private http: HttpClient) {
this.getMyLang();
}
async getMyLang() {
const headers = {
headers: new HttpHeaders({
'X-API-KEY': 'xxxxxx',
})
};
const param = new FormData();
param.append('language', 'en');
await this.http.post('api url', param, headers).subscribe((data1) => {
this.data.push(data1);
});
}```
when i call this method it pushes the data. after console this variable into component am getting following results.
console Screenshot enter code here

simple rest data provider won't accept Odata data

So the API I am using is using ODATA (https://www.odata.org/). As a result this is what it looks like when it's returned
```
{"#odata.context":"http://localhost:5001/api/$metadata#apemp",
"value":[
{"EmpID":1,
"Abbr":"Admin",
"BadgeNo":null,
"ColorRef":0,
"ContactMethodID":null,
"DateHired":"2018-05-25T16:42:57-05:00"}
]```
our data provider looks like this
import { stringify } from 'query-string';
import {
fetchUtils,
GET_LIST,
GET_ONE,
GET_MANY,
GET_MANY_REFERENCE,
CREATE,
UPDATE,
UPDATE_MANY,
DELETE,
DELETE_MANY
} from 'react-admin';
...
const convertHTTPResponse = (response, type, resource, params) => {
const { headers, json } = response;
switch (type) {
case GET_LIST:
return { data: json };
case GET_MANY_REFERENCE:
if (!headers.has('content-range')) {
throw new Error(
'The Content-Range header is missing in the HTTP Response. The simple REST data provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare Content-Range in the Access-Control-Expose-Headers header?'
);
}
return {
data: json,
total: parseInt(
headers
.get('content-range')
.split('/')
.pop(),
10
)
};
case CREATE:
return { data: { ...params.data, id: json.id } };
default:
return { data: json };
}
};
return (type, resource, params) => {
// simple-rest doesn't handle filters on UPDATE route, so we fallback to calling UPDATE n times instead
if (type === UPDATE_MANY) {
return Promise.all(
params.ids.map(id =>
httpClient(`${apiUrl}/${resource}/${id}`, {
method: 'PUT',
body: JSON.stringify(params.data)
})
)
).then(responses => ({
data: responses.map(response => response.json)
}));
}
// simple-rest doesn't handle filters on DELETE route, so we fallback to calling DELETE n times instead
if (type === DELETE_MANY) {
return Promise.all(
params.ids.map(id =>
httpClient(`${apiUrl}/${resource}/${id}`, {
method: 'DELETE'
})
)
).then(responses => ({
data: responses.map(response => response.json)
}));
}
const { url, options } = convertDataRequestToHTTP(type, resource, params);
return httpClient(url, options).then(response =>
convertHTTPResponse(response, type, resource, params)
);
};
};
so right now when I point that data provider to api endpoints it doesn't look the way the code is formatted.
I get the error
"The response to 'GET_LIST' must be like { data : [...] }, but the received data is not an array. The dataProvider is probably wrong for 'GET_LIST'"
I have used this dataprovider extensively with our previous API which returned data slightly differently.
since odata returns an object with the context and url as the items and the value with an array as the second item it doesn't work.
I really just need the array but don't know what I should be writing to get that.
I am also implementing DataProvider for OData and what you need to do is that you have to "wrap" your response data stored in value with data object.
But the array is in value prop and you can't just assert return { data: json }; like you do, because it expects object like {data: [0: {prop1: "hello", prop2: "world"}, 1: { ... }]} and you return this:
{
"#odata.context":"http://localhost:5001/api/$metadata#apemp",
"value":[
{
"EmpID":1,
"Abbr":"Admin",
"BadgeNo":null,
"ColorRef":0,
"ContactMethodID":null,
"DateHired":"2018-05-25T16:42:57-05:00"
}
]
}
So what you need to do is to assign value prop of response json, eg:
return { data: json.value };
So its actually pretty easy to fix

Angular2 Http post request not binding to ASP.NET 5 controller's action

I am initiating a post request from Angular2 to a ASP.NET 5 controller action. Angular is posting the data correctly and hitting the controller action but it is not being mapped to the parameters defined in controller action, the parameters are null. Meanwhile by inspecting through Request object Request.Form has the correct textual data but not binding to the model.
Angular
let body = JSON.stringify({ firstName: 'Ali' });
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
this.http.post(this.url, body, { headers: headers })
.subscribe(
(data) => {
console.log('Response received');
console.log(data);
},
(err) => { console.log('Error'); },
() => console.log('Authentication Complete')
);
ASP.NET
[HttpPost]
public IActionResult DemoAction(string firstName)
{
var req = Request;
return null;
}
Request.Form has data in the form like {\"firstName\":\"Ali\"} but the parameter firstName is null
You try to send a JSON content (created using the JSON.stringify method) with a content type url encoded form.
You should try to use the application/json one:
let body = JSON.stringify({ firstName: 'Ali' });
let headers = new Headers({ 'Content-Type': 'application/json' });
this.http.post(this.url, body, { headers: headers })
Edit
If you want to provide a form content, you could leverage the URLSearchParams class:
var params = new URLSearchParams();
params.set('firstName', 'Ali');
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
this.http.post(this.url, params.toString(), { headers: headers })
In this case you don't require to pass the header. look at here. you may try this.
this.http.post('/api/ControllerName/DemoAction?firstName=Ali')
.subscribe(
(data) => {
console.log('Response received');
console.log(data);
},
(err) => { console.log('Error'); },
() => console.log('Authentication Complete')
);
This will surely work.
Edited:
Figured out your problem.
First: When you are receiving paramter(s) at API end , you must use above portion.
second: When you are receiving object at API end, you must use below code.
I'm showing you with my setup as I don't know your object at server side.
let um=JSON.stringify({ Username: "Hello1",Password:"Hello2"});
let headers = new Headers({ 'Content-Type': 'application/json'});
this.http.post(this.url+'/Authentication',um,{ headers: headers })
.subscribe(...);
At server side I have following setup.
public class UserModel
{
public string Username { get; set; }
public string Password { get; set; }
}
[HttpPost]
public IHttpActionResult Authentication(UserModel um) // I m getting value here.
{
if (um.Username == "a" && um.Password == "a")
{
um.Username = um.Username;
um.Password = um.Password;
return Ok(um);
}
return NotFound();
}
Simple solution !! isn't it?
For me it works:
let headers = new Headers({ 'Content-Type': 'application/json' });
this.http.post(this.url, JSON.stringify({ firstName: 'Ali' }), { headers: headers })

Send data from js to controller

I have this ajax:
function sendData() {
var question = (document.getElementById('question').value).toString();
var c = (document.getElementById('c').value).toString();
$.ajax({
url: '/Home/InsertData',
type: 'POST',
data: {question:question, c:c},
// data: {},
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function () {
alert('suc');
},
error: function (error) {
alert('error');
}
});
}
in my HomeController, I have the function:
[HttpPost]
public void InsertData(string question, string c)
//public void InsertData()
{
this.insertDataToCustomers(question, c);
}
when I run it, I got an error of:
POST http://localhost:2124/Home/InsertData 500 (Internal Server Error)
If I didn't ask for input values in InsertData function and didn't send data in the ajax, it works. why can't I send data to InsertData function?
p.s. There are values in question and c
thank you!
Remove this:
contentType: 'application/json; charset=utf-8',
You are not sending any JSON to the server, so this is an incorrect content type for the request. You are sending a application/x-www-form-urlencoded request.
So:
function sendData() {
var question = $('#question').val();
var c = $('#c').val();
$.ajax({
url: '/Home/InsertData',
type: 'POST',
data: { question: question, c: c },
success: function () {
alert('suc');
},
error: function (error) {
alert('error');
}
});
}
Another problem with your code is that you indicated dataType: 'json' which means that you expect the server to return JSON but your controller action doesn't return anything. It's just a void method. In ASP.NET MVC controller actions should return ActionResults. So if you want to return some JSON for example to indicate the status of the operation you could have this:
[HttpPost]
public ActionResult InsertData(string question, string c)
{
this.insertDataToCustomers(question, c);
return Json(new { success = true });
}
Of course you could return an arbitrary object which will be JSON serialized and you will be able to access it in your success AJAX callback.

Resources