"Http failure during parsing for http://localhost:8080/" - json

extractData = (res: Response | any) => {
return res.body || {};
}
getData() {
return this.http.get('http://localhost:8080/test',
observe: 'response'
).pipe(
map(this.extractData));
}
The call is successful, I'm able to see the response in network tab but when I tried to log the response in console, I'm getting parse errors. Can anyone please help me

The getData() function doesn't have any return type mentioned.

Related

Javascript - Return json from fetch in an Object

I'm trying to make an application to get the recipes from https://edamam.com and I'm using fetch and Request object.
I need to make 3 request, and i thought that most beautiful way for do it is make an Object and a method that return the data in JSON.
I declarated into constructor a variable called this.dataJson, and i want to save there the data in JSON from the response. For that purpose i use this.
The problem is that i have a undefined variable.
.then( data => {this.dataJson=data;
console.log(data)} )
This is all my code.
class Recipe{
constructor(url){
this.url=url;
this.dataJson;
this.response;
}
getJson(){
var obj;
fetch(new Request(this.url,{method: 'GET'}))
.then( response => response.json())
.then( data => {this.dataJson=data;
console.log(data)} )
.catch( e => console.error( 'Something went wrong' ) );
}
getData(){
console.log("NO UNDFEIND"+this.dataJson);
}
}
const pa= new Recipe('https://api.edamam.com/search?...');
pa.getJson();
pa.getData();
I'm new studying OOP in JS and more new in Fetch requests...
If you guys can help me... Thanks very much!
Here's a solution using async-await (and a placeholder API):
class Recipe {
constructor(url) {
this.url = url;
this.dataJson;
this.response;
}
// the async keyword ensures that this function returns
// a Promise object -> we can use .then() later (1)
async getJson() {
try {
const response = await fetch(new Request(this.url, {
method: 'GET'
}))
const json = await response.json()
this.dataJson = json
} catch (e) {
console.error('Something went wrong', e)
}
}
getData() {
console.log("NO UNDFEIND:", this.dataJson);
}
}
const pa = new Recipe('https://jsonplaceholder.typicode.com/todos/1');
// 1 - here we can use the "then", as pa.getJson() returns
// a Promise object
pa.getJson()
.then(() => {
pa.getData()
});
If we want to stay closer to your code, then:
class Recipe {
constructor(url) {
this.url = url;
this.dataJson;
this.response;
}
getJson() {
// var obj; // not needed
// the "fetch" always returns a Promise object
return fetch(new Request(this.url, { // return the fetch!
method: 'GET'
}))
.then(response => response.json())
.then(data => {
this.dataJson = data;
// console.log(data) // not needed
})
.catch(e => console.error('Something went wrong'));
}
getData() {
console.log("NO UNDFEIND:", this.dataJson); // different syntax here
}
}
const pa = new Recipe('https://jsonplaceholder.typicode.com/todos/1');
// using "then", because the "fetch" returned a Promise object
pa.getJson()
.then(() => {
pa.getData();
});
The problem with your original code is that you initiate the request (pa.getJson()) and then immediately (on the next line) you want to read the data (pa.getData()). pa.getData() is called synchronously (so it happens in milliseconds), but the request is asynchronous - the data needs time to arrive (probably hundreds of milliseconds) - so, it's not there when you try to read it (it simply hasn't arrived yet).
To avoid this you have to use a technique to handle this asynchronous nature of the request:
use a callback function (blee - so last decade)
use a Promise object with then() (much better) or async-await (yeee!)
and call the pa.getData() when the response has arrived (inside the callback function, in the then() or after awaiting the result).

Stripe Error Message 405 - "append .json to uri to use rest api"

I'm using Stripe, and trying to send a test webhook to my URL and database hosted by Firebase. When I "send test webhook," I get the following error message in the Stripe Console:
Test Webhook Error: 405
"append .json to your request URI to use the rest API"
My code is a direct copy of the tutorial: https://github.com/GaryH21/Stripe-Webhooks-Tutorial/blob/master/functions/index.js
Here is the code of my index.js:
const functions = require('firebase-functions');
const stripe = require("stripe")(functions.config().keys.webhooks);
const admin = require('firebase-admin')
admin.initializeApp();
const endpointSecret = functions.config().keys.signing;
exports.events = functions.https.onRequest((request, response) => {
let sig = request.headers["stripe-signature"];
try {
let event = stripe.webhooks.constructEvent(request.rawBody, sig, endpointSecret)
return admin.database().ref('/events').push(event)
.then((snapshot) => {
return response.json({ received: true, ref: snapshot.ref.toString() })
})
.catch((err) => {
console.error(err)
return response.status(500).end() // error saving to database
})
} catch (err) {
return response.status(400).end() // signing signature failed
}
})
exports.exampleDataBaseTrigger = functions.database.ref('/events/{eventId}').onCreate((snapshot, context) => {
return console.log({
eventId: context.params.eventid,
data: snapshot.val()
})
})
The only time in the tutorial and in my code that .json is used is in the line: return response.json({ received: true, ref: snapshot.ref.toString() })
Should I be appending .json onto "request" somewhere, such as in request.RawBody?
It isn't a problem with the signing keys, as that would give the 400 Error message, which I already dealt with and fixed.
I would be happy to share the code of other files in my app, but as far as I can tell none of the rest is relevant to the problem. Thank you very much.

POSTing json to API with Angular 2/4

I am new to angular 4 and REST API development. I have developed a Login API in back-end and it works fine when I call it using Postman:
In the front-end application which is an Angular 4 project, I have created a service to call this login API. Here is the method I created in this service:
sendCredential(username: string, password: string) {
const url = 'http://localhost:8080/authenticate/user';
const body = '{"username": "' + username + '", "password": "' + password + '"}';
const headers = new Headers(
{
'Content-Type': 'application/json'
});
return this.http.post(url, body, {headers: headers});
}
My first question is:
Is this the correct way to pass the json object and call this API?
And I also created a component which calls the method in the service. Here is the method/event-handler I created in this component:
onSubmit(uname: string, pwd: string) {
this.loginService.sendCredential(uname, pwd).subscribe(
res => {
this.loggedIn = true;
localStorage.setItem('PortalAdminHasLoggedIn', 'true');
location.reload();
},
err => console.log(err)
);
}
My second question is:
How should I check whether a token is returned back or an error?
Question 1:
You do not need to stringify the body object when you do a http.post() in angular. Just use a normal object will do, and the Http class will help you parse it internally:
sendCredential(username: string, password: string) {
const url = 'http://localhost:8080/authenticate/user';
//do not need to stringify your body
const body = {
username, password
}
const headers = new Headers(
{
'Content-Type': 'application/json'
});
return this.http.post(url, body, {headers: headers});
}
Question 2:
As for your error, note that Angular also catch every http error. and by http error, it means that any status code that is <200 or >=300 will be an error. So only status codes that is in between 200 and 300 is considered successful. Upon an error received, angular will throw an Observable error, which you will need to handle explicitly (which you did it correctly):
onSubmit(uname: string, pwd: string) {
this.loginService.sendCredential(uname, pwd).subscribe(
res => {
//token should be in your res object
this.loggedIn = true;
localStorage.setItem('PortalAdminHasLoggedIn', 'true');
location.reload();
},
err => {
//handle your error here.
//there shouldn't be any token here
console.log(error);
}
);
}
With your above code, you should receive your token in your successful callback, and it will be in the res object. If there's an error, no token should be received and you should handle the error at the error callback.

Angular2 Http.Post - How to view webapi response

I'm new to Angular2/Typescript and I'm writing my first web application.
I'm trying to call a webapi using POST, it works, if I intercept the call using FIDDLER I can see the Json response.
Now, how I can log in the browser console the json ouput?
The code is this:
code call
var s = this.myService.doSearch();
s.subscribe(
data=> this.data = data,
error => this.errorMessage = <any>error
);
console.log(s);
service method
doSearch() {
var url = this.baseUrl;
return this.http.get(url)
.map(response => response.json())
.catch(this.handleError);
}
My question is: how and where I can view and manage the Json Output ?
Thanks
You need to console.log it after the async code is finished:
var s = this.myService.doSearch();
s.subscribe(
data=> {
this.data = data;
console.log(data);
},
error => this.errorMessage = <any>error
);
If you are debug or run your application in browser you can got to inspect and then move to the Network tab. In this tab select your POST Request and the go to the tab Response and voila there is your json Response
Edit:
To log all response data do this:
return this.http.get(url)
.map(res => res.json())
.subscribe(data => { console.log(data);})
.catch(this.handleError);
}
Try this this will print what you have in your returned observable .
var s = this.myService.doSearch();
s.subscribe(data=> {
this.data = data;
console.log(data);
},
error => this.errorMessage = <any>error
);
Always remember If you want to get data from observable.you need to subscribe it.
you can't log it like this console.log(s); because s returns an observable. you should subscribe and refer those data inside the subscribe .

How to handle Promise in nodejs

I'm trying to execute a callback function in nodejs, using expressjs and angular 2 (i don't know if the angular2 part it's relevant).
What I do is:
I have a formular in angular2, with that I send a get request to my API route, then I send the text field in the formular to the URL via get, then I do an MYSQL query to look into a phonebook database, and I'm expecting to get a complete user with his details, from the phonebook.
Formular:
<div class="container">
<div class="col-md-4">
<h1>Addressbook</h1>
<form [formGroup]="searchForm" (ngSubmit)="doSearch($event)">
<input formControlName="searchString" type="text" placeholder="Name">
<button type="submit">Search</button>
</form>
</div>
</div>
First function, doSearch:
doSearch(event) {
let formData = this.searchForm.value;
var searchString = this.searchForm.value.searchString;
this.http.get('/phonebook/search/'+searchString, function(req, res){}).subscribe(
function(response) {
console.log("Success Response");
},
function(error) { console.log("Error happened" + error)},
function() { console.log("the subscription is completed")}
);
}
This calls to the route sending a parameter, so not so hard.
Now the create router gets into the game:
public static create(router: Router, basePath: string) {
console.log("[SearchRoute::create] Creating routes for /search.");
// call the function for retrieving the address book results
router.get(basePath + "/search/:searchString", (req: Request, res: Response, next: NextFunction) => {
console.log("## [SearchRoute] Called GET /search.");
var object = searchUser(req);
console.log(object);
});
}
And finally, the function searchUser gets called:
function searchUser(req: Request) {
console.log("searchUser Function executed.");
var searchString = req.params.searchString;
var query = p_query('SELECT XXXX')
.then(function (results) {
console.log("query executed and all okay");
return (results);
})
.catch(function (error) {
console.error("Wooopsi", error);
});
console.log("query result: "+query);
}
Additionally, I post here the new query function that I build to be able to handle promises (which I don't know if it was the best choice):
function p_query(q) {
return new Promise(function (resolve, reject) {
// The Promise constructor should catch any errors thrown on
// this tick. Alternately, try/catch and reject(err) on catch.
myMYSQL.db.query(
q,
function (error, results) {
if (error)
reject(error);
resolve(results);
});
})
};
So, what I actually want to do, what's my issue?
I want to send the result of the query back to the client (the angular2 formular), and I was not being able to do it...
So after this really long post, I really appreciate if you read til here, and sorry for the complicated question!
PS: I know i explain myself really bad :(
Regards,
Daniel
In this official angular 2 documentation on the http client they propose to put the http logic into a separate service. I've setup it similar to the example just for a search.service.ts:
import { Injectable } from '#angular/core';
import { Http, Response,Headers, RequestOptions,URLSearchParams }
from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
#Injectable()
export class SearchService {
constructor(private http: Http) {
}
getSearchResult(searchString) : Observable<any> {
return this.http.get('/phonebook/search/'+searchString)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body;
}
private handleError (error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
return Observable.throw(errMsg);
}
}
In your component import the service and do the code snippets:
// don't forget to put the service in the app.modul or the component providers!
constructur(public mySearchService : SearchService) {}
// in your doSearch of your component:
doSearch(event) {
let formData = this.searchForm.value;
var searchString = this.searchForm.value.searchString;
mySearchService.getSearchResult(searchString).subscribe(
data => mylist.data, // or which datastructure I want to write to.
error => console.error(error) // or how I log the errors..
);
}
EDIT: The search_user in your database model:
function searchUser(searchString) {
console.log("searchUser Function executed.");
return myMYSQL.db.select('phonebookentry', {
pbe_lastname: searchString, pbe_syncstate: 'new'
}) // returning the promise/observable to the main function...
} // Currently I don't know, how the returned data looks like.
On the node/express side in the router send it with res.json EDIT: use asynchronous call to searchUser:
router.get(basePath + "/search/:searchString",
(req: Request, res: Response, next: NextFunction) => {
console.log("## [SearchRoute] Called GET /search.");
searchUser(req)
.then( data => res.json(data);console.log(data) )
.catch (error => console.log(error));
});
You should go with recursive callback with each query results try to enjoy the beauty of async platform.
Send data to client via
res.send(data);
Your answer it's completely perfect, i understand everything! The only problem that i'm facing now, its this one:
I'm calling the function searchUser, and it doesn't return anything, just an undefined object, so i quess i'm not doing the return correctly.
That's my searchUser function:
function searchUser(searchString) {
console.log("searchUser Function executed.");
myMYSQL.db.select('phonebookentry', {
pbe_lastname: searchString,
pbe_syncstate: 'new'
}).then(function (user) {
console.log("user before: "+user);
return (user);
}).catch(function (err) {
console.log(err);
})}
Thank you so much for your useful answer! I'm almost finished here