I'm trying to send a PUT request to a REST server that I have created, but no matter what I do the JSON object that is sent is empty. I have tried the server in Postmaster and it works as intended, so the problem must be with the React application.
This is the function that send the request:
handleSubmit(e) {
e.preventDefault();
const newBrand = this.state.brand
newBrand.description = this.state.editorState.getCurrentContent().getPlainText()
const json = JSON.stringify(newBrand)
console.log(json)
axios.put(`http://localhost:8080/BackendWiki/api/brands/${this.props.brandName}`, {json})
.then(res => {
console.log(res);
console.log(res.data);
})
}
The son object that's printed to the console looks like this:
{"id":56,"created":1597255927810,"updated":1597255927810,"links":[{"href":"http://localhost:8080/BackendWiki/api/brands/rolex","rel":"self","action":"GET"},{"href":"http://localhost:8080/BackendWiki/api/brands/rolex","rel":"self","action":"DELETE"},{"href":"http://localhost:8080/BackendWiki/api/brands/rolex","rel":"self","action":"PUT"}],"name":"Rolex","founded":0,"founder":null,"ceo":null,"headQuarters":null,"description":"more, more, more","text":[]}
I have implemented a get request that works like it should, which looks like this:
componentDidMount() {
Axios.get("http://localhost:8080/BackendWiki/api/brands/")
.then(res => {
const brands = res.data;
this.setState({brands})
})
}
Heres the code that handles the PUT request:
#PUT
#Path("/{name}")
#Consumes(MediaType.APPLICATION_JSON)
public Response updateBrand(#PathParam("name") String name, Brand updateBrand) {
System.out.println(updateBrand);
Brand oldBrand = brandDAO.getBrandByName(name.replaceAll("-", " "));
if (oldBrand != null) {
updateBrand.setId(oldBrand.getId());
brandDAO.update(updateBrand);
return Response
.status(200)
.entity(brandDAO.getBrandById(updateBrand.getId()))
// .header("Access-Control-Allow-Origin", "*")
.build();
} else {
return Response
.status(404)
//.header("Access-Control-Allow-Origin", "*")
.build();
}
}
I don't get any error messages either, so I'm a bit confused as to why the PUT does not work. Any help would be much appreciated.
Related
I have created an API using laravel to check if an email existed in database or not.
/**
*
* #param string $email
*/
public function checkUserEmail($email)
{
$userCount = User::where('email', $email);
if($userCount->count()){
return response()->json("true");
}else{
return response()->json("false");
}
}
I have tested this API in postman and it works as expected
Test using Postman
But, when I have use it in frontend it return an object not string!!
Frontend:
checkUserEmail(email : string){
return this.http.get<any>("http://127.0.0.1:8000/api/auth/user-email/"+email);
}
Browser console
In order to get the returned string using HttpClient in Angular you have to subscribe to Observable that returns.
Or you can do the async way using firstValueFrom from RxJS. Notice that response is in string because contains quotes ("false"), is better to just send true or false as boolean.
Here's the example:
public checkUserEmail(email: string): Observable<string> {
return this.http.get("http://127.0.0.1:8000/api/auth/user-email/" + email)
.pipe(
map((response: string) => response as string),
catchError( (errorObject) => {
return throwError(() => errorObject);
}
)
);
}
And now you can call this function subscribing or using async way:
Subscribe way (don't forget to unsubscribe):
checkIfEmailIsInDatabase(email: string): void {
this.checkUserEmail("some#email.com").subscribe(
(response: string) => {
// Do your stuff here, like setting variables or whatever
console.log("Response: ", response);
}
)
}
Async way:
async checkIfEmailIsInDatabase(email: string): Promise<void> {
let responseFromServer: string = await firstValueFrom(this.checkUserEmail(email));
console.log("Response from server: ", responseFromServer);
}
Hope it helps.
In Angular the return type of the httpClient's methods are Observables. So in your client code you have to subscribe to the observable. I also suggest so change "any" to string
i would like to post my array of objects data to .net core webservice.
this is my post method from react component.
async save(e) {
e.preventDefault();
var addition= this.state.addition;
addition.basket = this.state.basket;
const response = await axios.post("http://localhost:62524/api/SaveBasket/", querystring.stringify({ addition: addition}))
.then((error) => {
}).catch((error) => {
});
}
Data is not seeing after post.
this is my web service method,
[HttpPost]
public IActionResult SaveBasket(object addition)
{
var user = _userManager.GetUserId(HttpContext.User);
if (user != null && User.HasClaim(x => x.Type == "FIRMID:"))
{
//unitOfWork.Additions.SaveBasket(addition);
}
return BadRequest();
}
The data is sent to the above web service block.
getting something like this --->> [object]
How can i post the array of objects ?
I am using angular 4.2.6 for my application. I have a service like this
checkStaff(email: any) {
return this._http.post(this.url + "/Impsapi/getStaff", JSON.stringify(email)).map(
(resp) => resp
)
}
checkStaff(email:any){
return
this._http.post(this.url+"/Impsapi/getStaff",JSON.stringify(email)).map(
(resp)=> resp
)
}
this.loginServ.checkStaff(this.user)
.subscribe(
userData => {
this._return = userData;
console.log(this._return);
}
);
The Server returns JSON as response. but when i log the output, i get the below
logged response
please I need to consume the data in the body of the response. I have not been able convert the ._body to a proper json and use for the app. please help
The response data are in JSON string form. The app must parse that string into JavaScript objects by calling res.json().
return this._http.post(this.url + "/Impsapi/getStaff", JSON.stringify(email)).map(
(resp) => resp.json()
)
Update
try following code snippet
checkStaff(email: any) {
return this._http.post(this.url + "/Impsapi/getStaff", JSON.stringify(email))
.map(res => {return res.json()})
}
Try this:
this.loginServ.checkStaff(this.user)
.subscribe(
userData => {
this._return = userData.json();
console.log(this._return);
}
);
I mean your checkStaff:
checkStaff(email: any): Observable<Response> {
return this._http.post(this.url + "/Impsapi/getStaff", JSON.stringify(email));
}
export classMyResp
{
id: string;
/*so on...*/
}
This will give you the body of response If there is any.
I got my problem solved. My PHP is hosted on wampserver. In a way invalid JSON is always returned when i make call to the server. I had to use the ob_clean() function and everything is fine.
I'm working with Angular2 and a nodejs rest api. I have to do one or more http request for a same task so I'm using Observable.forkJoin() to wait for all of them to finish.
I map the result with the json parsing method and then subscribe to this result but I can't get any json properties from the result the way I used to do.
My service method returns the Observable.forkJoin() itself:
public rename(file:MyFile, newName:string){
let requests = new Array();
for(let i=0; i<file.sources.length; i++){
let url:string = this.serverUrl;
if(src.name === "src1"){
url += "rename/src1";
} else if (src.name === "src2" ){
url += "rename/src2";
}
requests[i] = this.http.get(url)
.map((res:Response) => res.json())
.catch(this.handleError);
}
return Observable.forkJoin(requests);
}
Then I subscribe to it in another method elsewhere:
this.api.rename(this.selectedFile, newFileName).subscribe(
rep => {
// The editor tells me "Property 'name' doesn't exist on type '{}'."
console.log(rep[0].name);
},
err => { console.error(err); }
);
The server correctly respond with the data I asked. The rep[0] is correctly set, it looks like this:
Object {name: "res.png", id: "HyrBvB6H-", size: 0, type: "", isShared: falseā¦}
I suppose it's a typing problem. Usually, with a simple http.get request, it returns an 'any' object. Here it returns an '[]{}' object. res[0] is an '{}' object and I can't get the json properties on it.
Am I using the Observer.forkJoin() correctly? Am I missing something?
Thanks in advance for help :)
If is the editor complaining and it is not an error when the code executes, it likely is a typing problem. You can set the return type of rename() to:
public rename(file:MyFile, newName:string): Observable<any[]> { }
This should allow you access properties of the inner results such as name.
Or you can type the rep array in subscribe() as any[]:
this.api.rename(this.selectedFile, newFileName).subscribe(
(rep: any[]) => {
console.log(rep[0].name);
},
err => { console.error(err); }
);
If all else fails or doesn't work for your solution you can use Type Assertion to treat rep as any[]:
this.api.rename(this.selectedFile, newFileName).subscribe(
rep => {
const responses = rep as any as any[];
console.log(responses[0].name);
},
err => { console.error(err); }
);
If the results structure is consistent across the different endpoints, it would best practice to create an interface/class to replace any[] with.
Hopefully that helps!
http.get is a asynchronous process, so you can't use for loop.
Syntactically you have to nest the gets inside forkJoin, so you have something like this. You can use the for loop to build an array of urls first.:
return Observable.forkJoin([
this.http.get(url[1]).map(res => res.json()),
this.http.get(url[2]).map(res => res.json()),
this.http.get(url[3]).map(res => res.json())
])
.map((data: any[]) => {
this.part1 = data[0];
this.part2 = data[1];
this.part3 = data[2];
});
I wonder if you may be able to do something like this. I'll have a try tomorrow. It's late..
return Observable.forkJoin(let req = [];
for(let i=0; i<file.sources.length; i++){
req[i] = this.http.get(url[i]).map(res => res.json())
}
)
I am creating a website that reads externally hosted json files and then uses node.js to populate the sites content.
Just to demonstrate what I'm after, this is a really simplified version of what I'm trying to do in node.js
var ids = [111, 222, 333];
ids.forEach(function(id){
var json = getJSONsomehow('http://www.website.com/'+id+'.json');
buildPageContent(json);
});
Is what I want to do possible?
(Marked as a duplicate of "How do I return the response from an asynchronous call?" see my comment below for my rebuttal)
You are trying to get it synchronously. What you should aim for instead, is not a function used like this:
var json = getJSONsomehow('http://www.website.com/'+id+'.json');
but more like this:
getJSONsomehow('http://www.website.com/'+id+'.json', function (err, json) {
if (err) {
// error
} else {
// your json can be used here
}
});
or like this:
getJSONsomehow('http://www.website.com/'+id+'.json')
.then(function (json) {
// you can use your json here
})
.catch(function (err) {
// error
});
You can use the request module to get your data with something like this:
var request = require('request');
var url = 'http://www.website.com/'+id+'.json';
request.get({url: url, json: true}, (err, res, data) => {
if (err) {
// handle error
} else if (res.statusCode === 200) {
// you can use data here - already parsed as json
} else {
// response other than 200 OK
}
});
For a working example see this answer.
For more info see: https://www.npmjs.com/package/request
I think problem is in async request. Function will return result before request finished.
AJAX_req.open( "GET", url, true );
Third parameter specified async request.
You should add handler and do all you want after request finished.
For example:
function AJAX_JSON_Req( url ) {
var AJAX_req = new XMLHttpRequest.XMLHttpRequest();
AJAX_req.open( "GET", url, true );
AJAX_req.setRequestHeader("Content-type", "application/json");
AJAX_req.onreadystatechange = function() {
if (AJAX_req.readyState == 4 && AJAX_req.status == 200) {
console.log(AJAX_req.responseText);
}
};
}