I've created a basic function in my component TS file to make a post request to retrieve data from a server. This function works fine but when I try to place the array of data into a variable so I can then write it on page via HTML, I can't seem to get the desired effect. It seems as if I'm doing something wrong which is causing the data not to be written into the "json" variable.
Here is my component TS, the variable I'm trying to pass the data through to is 'json';
postData = {
command: 'get_feature',
classes: 'F,G',
}
url = "http://c****************"
json;
constructor(private http: HttpClient) {
this.http.post(this.url, this.postData).toPromise().then((data:any) => {
console.log("post request in progress")
console.log("printing data array")
console.log(data)
this.json = data.json
console.log("printing json variable")
console.log(this.json)
console.log("post request finished")
});
}
And here is the basic HTML, it should only write the type of data, because I haven't stringified the data yet but it's writing absolutely nothing as if there is nothing in the variable.
<pre>
JSON test
{{ json }}
</pre>
the correct usage would be
// post is generic, so you can pass type here, if no type - pass any
this.http.post<ResponseType>(this.url, this.postData).toPromise().then((data) => {
this.json = data
});
and you can't just render the huge json in the mteplate, but you can try json pipe, to see what is inside of that json
<pre>
JSON test
{{ json | json }}
</pre>
Related
I am developing a front-end web application using Angular 11. This application uses several services which return data in JSON format.
I use the async / await javascript constructs and the Observables to get the answers from these services. This is an example my call:
let myResponse = await this.myService(this.myData);
myResponse.subscribe(
res => {
console.log("Res: ",res)
}, (error) => {
console.log("Error: ",error)
}
);
where this.myService contains the code doing the HTTP call using Angular httpClient.
Unfortunately a specific service (only one!) doesn't return data in JSON format but it returns a byte array (string that identifies a pdf -format application/pdf-).
Unfortunately this invocation causes a very strange error with code 200 OK:
How can I do to prevent res from being interpreted as JSON and therefore this error being reported? How can I read resreporting that it will not be in json format?
This service has no errors (with Postman it works perfectly). The problem is Javascript and Observable which are interpreted as JSON. How can I read the content of res in this case?
If a HTTP API call is not returning a JSON, just provide the proper value in the responseType option:
this.httpClient.get('<URL>', {
responseType: 'arraybuffer'
});
Ref: https://angular.io/api/common/http/HttpClient#description
I'm using axios to send a JSON object as a parameter to my api. Before it post request is fired, my data starts of as a JSON object. On the server side, when I console.log(req.params) the data is returned as such
[object Object]
When I used typeof, it returned a string. So then I went to use JSON.parse(). However, when I used that, it returned an error as such
SyntaxError: Unexpected token o in JSON at position 1
I looked for solutions, but nothing I tried seemed to work. Now I'm thinking I'm sending the data to the server incorrectly.
Here's my post request using axios:
createMedia: async function(mediaData) {
console.log("SAVING MEDIA OBJECT");
console.log(typeof mediaData)
let json = await axios.post(`http://localhost:3001/api/media/new/${mediaData}`)
return json;
}
Any thoughts on how I can solve this?
You need to update your code using axios to provide the mediaData in the body of the request instead of the URL:
createMedia: async function(mediaData) {
console.log("SAVING MEDIA OBJECT");
console.log(typeof mediaData)
let json = await axios.post(`http://localhost:3001/api/media/new/`, mediaData)
return json;
}
In the backend (assuming you're using express here), you need to configure your application to use bodyParser:
var express = require('express')
, app = express.createServer();
app.use(express.bodyParser());
And then in your controller update your console.log(req.params) to console.log(req.body); then restart your node server
hello everyone i want to render the json response returned from server for that i'm using map method. But there is a mistake in my code please help me to figure it..The response i'm getting is
response.json
{
status: true
token:{
access_token: "BhTErqRtliUG#8"
client_id: "ck4fLr08YHkW2y"
expires: "2018-02-19 03:51:50"
scope: null
user_id:465
},
user:{
avatar: "https://www.indianeconomy.net/lms/wp-content/uploads/2017/11/favicon.png"
email: "tet#wehubs.afs"
id:465
name: "testere"
sub:""
}
}
I've tried this
fetch(''{
.... }).then((responseData)=>{
this.setState({
userdetail: responseData,
loaded:true,
})
}
render(){
return this.state.userdetail.map(user=>{
<Text>{token.access_token}</Text>
})
}
How to use map method over above json response?
The other comments are correct. You cannot map over an object like this. There are ways you can iterate over object properties:
for(let prop in object) {
console.log(object[prop]);
}
However, in your example the objects don't have any similarities so you would not get any benefit from iterating over them.
If instead, you wanted to display the access token, you would do the following:
return (
<Text>{this.state.userdetail.token.access_token}</Text>
);
json string shown by you is not a valid json you can validate here https://jsonlint.com/
i am not sure about react but you mention dict so in python if you have valid json
you can map it with dict like this
json.loads(json_string)
POST ing json from javascript to server in Play Framework:
var myJson = {"name": "joe", "age":20};
var obj = JSON.parse(myJson);
$.ajax(jsRoutes.controllers.MyController.create(obj));
Now, I have the javascript router configured fine. If i recieve the obj as a string I can print it out to the console just fine.
routes.conf:
POST /person/add controllers.MyController.createFromAjax(ajax: String)
BUT, I want to write the json to MongoDB using an Async promise which Activator gives the compile time error:
scala.concurrent.Future[play.api.mvc.Result][error] cannot be applied to (String)
I have other routes that take no parameters that receive json using Postman and write it to MongoDB just fine
routes.conf
POST /heartrates/bulk controllers.HRController.createFromJson
If I omit the parameter on the route that receives the json from Ajax instead of using Postman I get a HTTP 400 error in the browser.
POST http://localhost:9000/person/add 400 (Bad Request)
SO, my question is, Ajax needs a parameter but String wont work. Play documentation says json is always received as a String. What am I doing wrong here?
Scala Controller Code taken from Lightbend seed Play.Reactive.MongoDB:
def createBulkFromAjax = Action.async(parse.json) { request =>
val documents = for {
heartRate <- request.body.asOpt[JsArray].toStream
maybeHeartRate <- heartRate.value
validHeartRate <- maybeHeartRate.transform(transformer).asOpt.toList
} yield validHeartRate
for {
heartRate <- hrFuture
multiResult <- heartRate.bulkInsert(documents = documents, ordered = true)
} yield {
Logger.debug(s"Successfully inserted with multiResult: $multiResult")
Created(s"Created ${multiResult.n} heartRate")
}
}
I think you're getting mixed up between the parameters you pass to your Action as part of the jsRoutes call, and parameters that get passed to endpoints (i.e. the query string, query parameters etc).
Play will return a 400 Bad Request if you've declared a non-optional parameter (like you did with ajax: String) and you don't then actually supply it in your request.
While conceptually you are passing obj to your action, it's not as a query parameter - you've declared that your endpoint expects an HTTP POST - so the JSON should be in the HTTP request body. Notice your other endpoints don't take any query parameters.
So step 1 is to fix your routes file (I've renamed your method to match your other existing working one):
POST /person/add controllers.MyController.createFromJson
If you look at the Play documentation for the Javascript reverse router, you'll see that you'll need to set the type (aka HTTP method) if you're doing something other than a GET. So, step 2, here's what your Javascript should look like to achieve a POST:
var myJson = {"name": "joe", "age":20};
var obj = JSON.stringify(myJson);
var r = controllers.MyController.createFromJson;
$.ajax({url: r.url, type: r.type, data: obj });
After those changes you should be good; your controller code looks fine. If you still get 400 Bad Request responses, check that jQuery is setting your Content-Type header correctly - you may need to use the contentType option in the jQuery $.ajax call.
Edit after still getting 400 errors:
I've just noticed that you were using JSON.parse in your Javascript - as per this answer you should be using JSON.stringify to convert an object into something jQuery can send - otherwise it may try to URLEncode the data and/or send the fields as query parameters.
The other thing to look at is whether the JSON you are sending actually agrees with what you're trying to parse it as. I'm not sure if you've provided a simplified version for this question but it looks like you're trying to parse:
{"name": "joe", "age":20}
Using:
request.body.asOpt[JsArray]
Which will always result in a None - you didn't give it an array.
The Answer to ajax javascript routes in Play Framework 2.5 for ReativeMongo:
routes.conf:
GET /javascriptRoutes controllers.HRController.javascriptRoutes
HRController:
def javascriptRoutes = Action { implicit request =>
Ok(
JavaScriptReverseRouter("jsRoutes")(
routes.javascript.HRController.createBulkFromAjax
)
).as("text/javascript")
}
routes.conf:
POST /heartrates/add controllers.HRController.createBulkFromAjax
main.scala.html:
<script type="text/javascript" src="#routes.HRController.javascriptRoutes"></script>
javascript:
var r = jsRoutes.controllers.HRController.createBulkFromAjax();
$.ajax({url: r.url, type: r.type, contentType: "application/json", data: JsonString });
HRController:
def createBulkFromAjax = Action.async(parse.json) { request =>
//Transformation silent in case of failures.
val documents = for {
heartRate <- request.body.asOpt[JsArray].toStream
maybeHeartRate <- heartRate.value
validHeartRate <- maybeHeartRate.transform(transformer).asOpt.toList
} yield validHeartRate
for {
heartRate <- hrFuture
multiResult <- heartRate.bulkInsert(documents = documents, ordered = true)
} yield {
Logger.debug(s"Successfully inserted with multiResult: $multiResult")
Created(s"Created ${multiResult.n} heartRate")
}
}
HRController.createBulkFromAjax was built from a Lightbend activator ui seed example called play.ReactiveMogno
I am trying to render a json response from grails controller action. Here is my code:
render ([message:"voila Sent Successfully!"]) as JSON
But in the gsp, it is rendering like:
['message':'Email Sent Successfully!']
Above text is actually a string(as its typeof in jquery ajax call gives a string in the success event handler), so how do I render it as a JSON?
I am using grails 2.4.5 and the JSON class is actually grails.converters.JSON (not grails.converters.deep.JSON)
Just do as
render ([message:"voila Sent Successfully!"] as JSON ) i.e inserting as JSON
within parentheses.
I'd like to expose another answer, which avoids an issue like one that I already found in IE. Some older IE versions could try to download your JSON as a file.
Generate your JSON response from your collection/map and then render it as a string, so:
import grails.converters.JSON
def YourService
def yourControllerNameHere(){
def result = YourService.generatesYourResult(),
resultJSON = result as JSON
render resultJSON.toString()
}
Then, in your ajax, parse this string as JSON-object using jQuery, that is:
$.ajax({
url : WEB_ROOT + 'yourUrl/yourControllerNameHere',
type : 'post',
dataType: 'text',
success : function(resultStr) {
var result = $.parseJSON(resultStr);
alert('this is your response type: ' + (typeof result));
// this is your response type: object
}
});