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

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

Related

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

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!

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

How to get value of form filed card_number to pass to the controller?

How would I get the value of card_number to pass to the controller?
Every time I submit the form I get NULL in the form variable
View:
#Html.EditorFor(model => model.card_number, new { htmlAttributes = new { #id = "card_number" } })
<script>
var frm = $('#formFilter');
function OnFormSubmit() {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: function (frm) {
frm.card_number = $('#card_number').val();
},
success: function (data) {
$("#dataResult").html(data);
$('#dataTable').DataTable({
"dom": 'lifrtp'
});
}
});
}
</script>
controller:
private List<testtest> GetListChanges(Report changeControl)
{
...logic here....
return returnListhere;
}
The data property of the $.ajax method options should be an object or string which represents your data. With your current code you are setting a function to that.
var d = {
card_number: "1234",
someOtherPropertyNameOfReport: "Hello"
};
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: JSON.stringify(d),
contentType:"application/json",
success: function (data) {
console.log(data);
}
});
Now jquery will send the request with Content-Type request header value set to application/json and request data (the stringified version of your JavaScript object) in the request body and model binder will be able to properly read and map it to your view model, assuming the structure of the view model matches with your JavaScript object structure.
As suggested in the comment, try to use serialize() method. It is simply and you do not need to manually build the object.
Also your controller action method should be public

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

mvc json request life cycle

I'm pretty new to asp.net and MVC.
I was trying to use json request and populate some text boxes.
but I noticed when I'm using json, I can not access values of the other text boxes in my view.
for example
string s2 = Request.Form["selectedTestCategory"];
would generate s2 = null, when I debug.
but if I put a submit button on the page, the value is not null. (And so far I know I can only pass one parameter to my JSON method in controller)
My question is what happens when I start a json request? and why I can not get a value from Request.Form[...]
Thanks,
Update:
This is my json
<script>
$(document).ready(function() {
$('select#testStationUniqueId').change(function() {
var testStation = $(this).val();
$.ajaxSetup({ cache: false });
$.ajax({
url: "TestInput/getTestStationInformation/" + testStation,
type: 'post',
success: function(data) {
$('#driveDetailDiv').empty();
for (var i = 0; i < data.length; i++) {
$.post('TestInput/Details/', { id: data[i] }, function(data2) {
$('#driveDetailDiv').append(data2);
});
}
}
});
});
});
And this is in my controller
public PartialViewResult Details(string id)
{
//DriveDetails t = new DriveDetails(id);
//return PartialView("DriveDetailsPartial", t);
test_instance_input_model ti = new test_instance_input_model();
string s2 = Request.Form["selectedTestCategory"];
repository.setTestInstanceAttributes(ti, id);
return PartialView("TestInstancePartial", ti);
}
the s2 is null in Details, but if I use a submit button, it will have the correct value.
so I'm trying to figure out why it is null when I send a json request.
In your JavaScript your not including any data in the jQuery ajax request (see jQuery ajax). Therefore jQuery isn't adding any request parameters. You need to include a data object which jQuery will turn into parameters i.e. the more properties in the data object the more parameters in the request.
$.ajax({
url: '',
data: { selectedTestCategory: 'category' },
dataType: 'post',
success: function() {}
});
Also, in your controller you can shortcut to the request parameter.
string s2 = Request["selectedTestCategory"];

Resources