I have a json file that I want to consume in my angular app via an http get request
My plan is to host the static json file in my amazon s3 bucket with public access. The problem is trying to consume it in my angular app.
getRanges() {
return this.http.get("http://publicurl.json")
.map(res => res.json(),
(error) => this.sharedAppFunctions.showToast(error)
);
}
This is failing probably because it not a json response type.
This was the solution
getRanges() {
return this.http.get("https://xxx/Ranging.json")
.map(this.extractData);
}
private extractData(res: Response) {
let body = res.json();
return body.data || {};
}
Related
I am trying to create an endpoint in a HTTP API that receives data periodically from remote devices.
There is a technological shift happening in this project where devices have previously reported data in XML whereas future implementations will shift towards JSON.
I am writing this API in NestJS (7.x) and TypeScript. Data will be coming in through the same endpoint (POST /) and data format is differentiated by the Content-Type header.
#Controller()
export class IngressController {
constructor(private readonly ingressService: IngressService) {
}
/* ... */
#Post('')
#Header('Cache-Control', 'none')
#HttpCode(HttpStatus.NO_CONTENT)
public async receive(
#Headers('Content-Type') contentType: string,
#Req() req: any,
#Body() body: string,
): Promise<InsertResponse> {
if (IngressController.isJson(contentType)) {
return { inserted: await this.ingressService.insertJsonString(req.body) };
}
if (IngressController.isXml(contentType)) {
return { inserted: await this.ingressService.insertXmlString(req.body) };
}
throw new BadRequestException(contentType, 'Unsupported Content-Type');
}
/* ... */
}
Future devices will report data in JSON (indicated by the Content-Type: application/json header in the HTTP request), legacy devices report in XML (Content-Type: application/xml).
It works splendidly for JSON. However, my problem is that req.body (or body respectively) is an empty object in the XML case. I presume the NestJS middleware is doing something and getting confused by XML, but I have found no hints as to allow XML payloads side-by-side with JSON. I don't mind parsing it manually.
As you suspected NestJS has a built-in bodyparser that will not be able to parse xml. What you could do is to plug in a custom middleware where you decide whether to parse the request body as xml or pass the request on the the next handler.
Something like this should work (I'm using express-xml-bodyparser in this example):
import {NestFactory} from '#nestjs/core';
import {AppModule} from './app.module';
import {Request} from "express";
const xmlParser = require('express-xml-bodyparser');
const xmlParserMidleware = xmlParser();
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use((req: Request, res: any, next: any) => {
if (req.path.includes("/api/json-or-xml-handler") && req.header('Content-Type')?.includes('xml')) {
return xmlParserMidleware(req, res, next);
}
next();
});
await app.listen(8020);
}
bootstrap();
Then, in your controller body will either be the parsed json-object or an object representation of your xml:
#Controller()
export class TestControllerController {
#Post('/api/json-or-xml-handler')
receive(#Body() body: any) {
console.log(body);
// ...
}
}
I am trying to store data from my angular app into a JSON. The JSON is stored within the assets folder of my app and I have the app on a server.
I am using HttpClient to POST data to the JSON. It says it is successful but it does not actually send the data.
This is my .ts:
import { HttpClient } from '#angular/common/http'
import { HttpHeaders } from '#angular/common/http'
export class OpscreenComponent implements OnInit {
constructor(private httpService: HttpClient ) { }
ngOnInit() {
var jsonpost = {
"testing": [
{
"anothertest":"here",
"anumber": 1
}
]
}
var headers = new HttpHeaders({
'Content-Type': 'application/json'
})
var options = { headers: headers }
this.httpService.post("http://servername/angularApp/assets/testing.json", jsonpost, options)
.subscribe(
data=> {
console.log("POST Request is Successful ", data )
},
error => {
console.log("Error ", error)
}
)
}
}
I get no error messages and the request is successful because it is logging POST Request is Successful null in the console.
The json is blank to start and after the POST success it is still blank (hence the null in the console.)
Why is it not posting the data to the JSON?
I am using httpClient for get so I know it is imported correctly.
this.httpService.request('POST', `${YourTestUri}`, { body: jsonpost, headers: headers }).pipe( switchMap( (response: any) => ... ) );
What you are trying to do is write files to disk, unfortunately, The HttpClient of Angular can't write files to disk. At least not with the classic implementation.
You probably prefer to add a server who can write to the disk, and your HttpClient will hit the server with the corresponding data.
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 am looking for data in an API via Get request, I need the data inside my OnInit to use in composing other data. The problem is that the method is being called but it is as an async method (without await), it passes everywhere but when the return is obtained the excution of the main method has already been finished with no results. I tried the implementation of asynchronous methods but it did not solve.
service:
getObjects(): MyClass[] {
let objects = new Array<MyClass>();
this.obterTodos<MyClass>(this.uriApi)
.map(res => res.map(x => new MyClass(x.Description, x.Id)))
.subscribe(entities => {
objects = entities;
});
return objects ;
}
get request
public getObjects<TEntity>(url: string): Observable<TEntity[]> {
return this.httpService
.get(this.serviceUrl + url, this.options)
.map(res => res.json())
.catch(this.handleError);
}
component:
ngOnInit() {
this.myObjects= this.setorService.obterSetores();
console.log('this.myObjects is empty here');
}
so you'll want to subscribe to your observable in the component. This is typically done so the component can determine when the http request should be ran & so the component can wait for the http request to finish (and follow with some logic).
// subscribe to observable somewhere in your component (like ngOnInit)
this.setorService.obterSetores().subscribe(
res => {
this.myObjects = res;
},
err => {}
)
now the component knows when the http request finishes
I'm new to REST services, I have an Angular2 client calling a RestEasy JAX-RS service. All I am trying to get is a "Hello World" message in JSON format. I was expecting only a JSON object, but I get my response with the following structure:
_body: "{"message":"Hello World!!"}"
headers: t
ok: true
status: 200
statusText: "OK"
type: 2
url: "http://localhost:8080/helloapp/rest/hello/world"
__proto__: ...
My question is, Is that the way it should be?
I mean, I thought I would be able to access the JSON object straight from the response. Something like
this.service.getHello()
.then( result => {
console.log(JSON.parse(result)); //{message: "Hello World"}
this.message = JSON.parse(result).message;
});
But I actually have to get it from _body:
this.service.getHello()
.then( result => {
this.message = JSON.parse(result._body).message;
console.log(this.message);//Hello World
});
Is it a RestEasy configuration thing, is there a way to change that?
Or
Should I consider that I will always have a field _body in my response with my data, and that's the default response structure?
For eventual consideration, here is my backend code:
HelloWorld Service:
#Path("/hello")
#Produces({ "application/json" })
#Consumes({ "application/json" })
public class HelloWorld {
public HelloWorld() {}
#GET
#Path("/world")
public Message getHello(){
return new Message("Hello World!!");
}
}
My RestEasy version is 3.1.1.Final running in Wildfly 10.1.0.Final
What you're getting back is the Response object from the Http request. This is what all Http operations will return. The easiest way to parse the JSON from that is to just call the json() method on it
this.service.getHello()
.then((res: Response) => {
let obj = res.json();
});
If you want the getHello to just return the object without having to parse it (on the calling client), then you can do it inside the getHello method by mapping it (using the Observable.map operation)
getHello() {
this.http.get(..)
.map((res: Response) => res.json())
.toPromise();
}
As peeskillet says above, you're getting back the entire Response from the request, and while sometimes you may want to examine the headers, perhaps to handle the different return conditions (retry or redirect on 4xx or 5xx responses for example), most of the time we assume a successful request and we just want the payload.
Angular2 encourages the use of Observables, so your service might look something like this:
getHello()
{
return this.http.get(http://localhost:8080/helloapp/rest/hello/world)
}
And your component may look something like this:
data: string;
ngOnInit() {
this.service
.getHello()
.map(response => response.json())
.subscribe (
data => {
this.data = data,
},
err => console.log('Error',err),
() => console.log('data',this.data)
);
}
You call the service, which is an http.get() and returns an Observable object, and we use .map to parse the response as JSON, which also returns an Observable, which we subscribe to.
Subscribe has three callback functions,
.subscribe(success, failure, complete)
In the example above on success we assign the payload - data - to this.data, if the subscribe fails, you log the error, and when it completes, we can do whatever we like, but in this case, we log this.data to the console - that's optional, but I log out the results while developing and then strip them out later.