I'm working on a dialgflow V1 bot.
I'm really inspired by this repository : https://github.com/mlabouardy/dialogflow-angular5
I have an issue in my dialogflow service.
I can't post query with special characters.
here is my diaogflow service working but when i pass my query it is code to utf-8 which broke dialogflow :
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/Rx'
import { environment } from '../../environments/environment';
#Injectable()
export class DialogflowService {
private baseURL: string = "https://api.dialogflow.com/v1/query?v=20170712";
private token: string = environment.dialogFlowToken;
constructor(private http: Http){}
public getResponse(query: string){
let data = {
query : query,
lang: 'fr',
sessionId: '12345'
}
return this.http
.post(`${this.baseURL}`, data, {headers: this.getHeaders()})
.map(res => {
return res.json()
})
}
public getHeaders(){
let headers = new Headers();
headers.append('Authorization', `Bearer ${this.token}`);
return headers;
}
}
I tried to use :
encode_utf8(s) {
return unescape(encodeURIComponent(s));
}
decode_utf8(s) {
return decodeURIComponent(escape(s));
}
But it didn't work
Do you have a suggestion ?
Thanks a lot.
Romain
try to force it with additional header and see if that works.
{'Content-Type' : 'application/json; charset=UTF-8'}
Related
While using Angular HttpClient post, it seems the default is to treat the response as JSON string. This caused error even for 201 response when the response body is empty as empty string "" fails JSON.parse().
The solution is to specify responseType: "text" as additional option, so that empty body is not treated as error.
However, the API endpoint does return error description in JSON when the request fails (i.e. empty on success, JSON on error).
How do you construct the HttpClient post so that I can get the error message object back when it fails and success does not count as error?
e.g.:
.subscribe(() => {
// do something for success, no return object as the body is empty
, error => {
// do something with the returned error object
// right now success is still counted as an error due to the issue above
}
);
A server that returns response code 200 or 201 with an empty response body and Content-Type specified as application/json is misconfigured, since an empty string is not valid JSON.
As the OP indicated, specifying responseType: "text" fixes the error, since the empty body is not parsed as JSON.
A workaround is to proceed with responseType: "text" and check if the response body is empty. If the response body is not empty, then call JSON.parse(response).
Example
import { Injectable } from '#angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
type HttpOptions = {
headers?: HttpHeaders | { [header: string]: string | string[]; };
observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; };
reportProgress?: boolean; responseType?: "json" /* or "text" as "json" */;
withCredentials?: boolean;
}
let get_http_options_text = (): HttpOptions => {
return {
headers: {'Content-Type': 'text/plain'},
observe: "body",
responseType: "text" as "json", // #see https://github.com/angular/angular/issues/18586
withCredentials: true
}
}
#Injectable()
export class MyHttpService {
constructor(private http: HttpClient) {}
public post_body_as_string(url: string, body: any, http_params: HttpParams = null):
Observable<any> {
let options = get_http_options_text();
if (http_params != null) {
options['params'] = http_params;
}
return this.http.post<string>(url, body, options).pipe(
map(response => {
if (response !== '') {
return JSON.parse(response);
} else {
return {}
}
})
);
}
}
I am new to Angular 6, and I am having one issue with custom header for Authorisation. I am setting a Oauth2 token in Authorisation header but it is not going along with request. I have done a lot of googling but none of the solution solves my problem. Below I am adding code.
Custom header in request:
getCurrentUser() {
let token = this.cookie.get('token');
return this.http.get<User[]>(serverurl + 'getUser',{
headers: new HttpHeaders().set('Authorization', token),
}) // this.httpOptions
.pipe(
tap(user => this.log(`fetched current user`)),
catchError(this.handleError('currentUser', []))
);
}
As request Interceptor:
import { AuthService } from '../services/auth.service';
import { Injectable } from '#angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '#angular/common/http';
import { Observable } from 'rxjs';
import { CookieService } from 'ngx-cookie-service';
#Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private auth: AuthService, private cookie: CookieService) { }
intercept(req: HttpRequest<any>, next: HttpHandler) {
let token = this.cookie.get('token');
let changedRequest = req;
// HttpHeader object immutable - copy values
const headerSettings: { [name: string]: string | string[]; } = {};
if (token) {
headerSettings['Authorization'] = 'Bearer ' + token;
}
// headerSettings['Content-Type'] = 'application/json';
const newHeader = new HttpHeaders(headerSettings);
changedRequest = req.clone({
headers: newHeader
});
return next.handle(changedRequest);
}
}
It gives following request:
Authorisation token is added in Access-control-request-Header instead of Authorisation itself. And I don't see Authorisation header in request.
Thanks in Advance...!
After searching a lot for this I found the solution for this:
There is no problem in the code, since you are using Cross Origin request it first sent OPTIONS request to the server. In order to fix this I added following piece of code in my server configuration section:
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
It has nothing to do with Angular 6. Basically you need to Allow OPTIONS method for all URLs from server side. And it will work. :)
I have .Net 4.6.2 VS 2017 Mvc application, with Angular 5, "rxjs": "^5.5.10"
I am trying to get data for Kendo UI grid through controller. The controller is returning data which I can see, but in the service class at code .map(response => response.json()), it says illegal return statement.(Please see attached image)
err img2
Here is vto.service.ts
import { Injectable } from '#angular/core';
import { VTO } from './vto';
import { Http, HttpModule, Headers, Response } from '#angular/http';
import { HttpClientModule, HttpClient, HttpHeaders} from '#angular/common/http';
import { Location, LocationStrategy, PathLocationStrategy } from '#angular/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
import {
toDataSourceRequestString,
translateDataSourceResultGroups,
translateAggregateResults,
DataResult,
DataSourceRequestState
} from '#progress/kendo-data-query';
import 'rxjs/add/operator/map';
import { GridDataResult, DataStateChangeEvent } from '#progress/kendo-angular-grid';
#Injectable()
export class Vtos {
// private vtoUrl = location.href.replace(location.hash, '') + '/home/GetVtos';
private vtoUrl = 'http://localhost:63213/Home/GetVtos';
constructor(private http: Http) { }
public getVtos(state: DataSourceRequestState): Observable<DataResult> {
const queryStr = `${toDataSourceRequestString(state)}`; //serialize the state
const hasGroups = state.group && state.group.length;
return this.http
.get(`${this.vtoUrl}?${queryStr}`) //send the state to the server
.map(response => response.json())
.map(({ data, total/*, aggregateResults*/ }) => // process the response
(<GridDataResult>{
//if there are groups convert them to compatible format
data: hasGroups ? translateDataSourceResultGroups(data) : data,
total: total,
// convert the aggregates if such exists
//aggregateResult: translateAggregateResults(aggregateResults)
}))
}
}
HomeController call to GetVots
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using VTO.DTO;
using VTO.DAL;
using Kendo.Mvc.UI;
using Kendo.Mvc.Extensions;
namespace VTO.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpGet]
public JsonResult GetVtos([DataSourceRequest]DataSourceRequest request)
{
return new JsonResult
{
ContentType = "application/json",
Data = Vto.GetVtos().ToDataSourceResult(request),
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
MaxJsonLength = int.MaxValue
};
}
}
A couple of observations here, this module is deprecated. See details here. Remove it from your app.
import { Http, HttpModule, Headers, Response } from '#angular/http';
You should use HttpClientModule,
import { HttpClient, HttpHeaders} from '#angular/common/http';
Keep it mind you have to import HttpClientModule on your app.module.ts (or any other module you have a dependency for it)
import { HttpClientModule } from '#angular/common/http';
Since HttpClientModule came into play. You not longer need for response.json(). Now HttpClient.get() returns an Observable of typed HttpResponse rather than just the JSON data. See docs. (vto.service.ts)
Remove,
.map(response => response.json())
Then you have,
constructor(private http: HttpClient) { }
public getVtos(state: DataSourceRequestState): Observable<DataResult> {
...
return this.http
.get(`${this.vtoUrl}?${queryStr}`)
.map(({ data, total/*, aggregateResults*/ }) =>
(<GridDataResult>{
data: hasGroups ? translateDataSourceResultGroups(data) : data,
total: total,
translateAggregateResults(aggregateResults)
}))
}
Sharing what worked for me. As Luillyfe mentioned Http is now deprecated, HttpClient is to be used. The returned response is already in Json, so no longer need to use .Json method.
constructor(private http: HttpClient) { }
public getVtos(state: DataSourceRequestState): Observable<DataResult> {
const queryStr = `${toDataSourceRequestString(state)}`; //serialize the state
const hasGroups = state.group && state.group.length;
return this.http
.get(`${this.vtoUrl}?${queryStr}`) //send the state to the server
.pipe(
map(<DataResult>({ Data, Total/*, aggregateResults*/ }) => {// process the response
console.log(Data);
return (<GridDataResult>{
data: hasGroups ? translateDataSourceResultGroups(Data) : Data.map(item => {
item.ReportDate = new Date(item.ReportDate); // convert to actual JavaScript date object
return item;
}),
total: Total
})
})
)
}
I'm trying to use Angular4 HttpClient with an observable object that I define. Unfortunately, I can't seem to map the response to the object.
The problem seems to be that I'm using httpclient (which returns json implicitly so there in no response.json() function) and as I understand it http is being deprecated? Anyway because of this the response.json() causes an error;
ERROR TypeError: response.json is not a function
The code;
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Observable';
import {JsonpModule, Jsonp, Response} from '#angular/http';
export class BucketList {
constructor(public name: string,
public creationdate: string) {
}
}
#Injectable()
export class DocumentSearchService {
constructor(private _http : HttpClient) { }
getBucketList () : Observable<BucketList> {
let serviceURL = "http://localhost:3000/listBuckets";
return this._http.get(serviceURL, {withCredentials: true, responseType: 'json'})
.map((response: Response) => <BucketList>(response.json())
.catch((error: any) => window.console.log(error)));
}
}
ngOnInit() {
// this.BucketList = this.DocumentSearchService.getBucketList
this.BucketList =
this.DocumentSearchService.getBucketList().subscribe(value => {
}
Could someone point me in the right direction please? Googling and searching on SO have yielded no answers so far...
Thanks.
responseType: 'json' and response.json() can be omitted because they are implied by default:
The responseType value determines how a successful response body will be parsed. If responseType is the default json, a type interface for the resulting object may be passed as a type parameter to request().
<...>
get<T>(url: string, options: {
headers?: HttpHeaders,
observe: 'events',
params?: HttpParams,
reportProgress?: boolean,
responseType?: 'json',
withCredentials?: boolean,
}): Observable<HttpEvent<T>>
Construct a GET request which interprets the body as JSON and returns the full event stream.
I'm having an error in Ionic 2 "SyntaxError: Unexpected token < in JSON at position 3". My json format is correctly structured using spring boot.
Below is my spring boot code.
Appreciate your help.
#RequestMapping(value="/myview", method=RequestMethod.GET, produces = "application/json")
#ResponseBody
List<Client> myView( #ModelAttribute("client") Client client){
List<Client> data=(List<Client>) clientService.getAll();
return data;
}
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class PeopleService {
people: any;
constructor(public http: Http) {}
load(){
if (this.people) {
return Promise.resolve(this.people);
}
return new Promise(resolve => {
this.http.get('http://localhost:8080/myview')
.map((res)=>res.json()).subscribe((data)=>{
console.log(data);
this.people=data;
resolve(this.people);
}, err=>{console.log(err)});
});
}// end load function
}
JSON from /myview
[{"id":1,"username":"donald#yahoo.com","policy":"V121293031","name":"Donald","mobile":"0504735260","email":"dcgatan#gmail.com","address":"Dafza Dubai","amount":800.98,"datetimestamp":1472861297000},{"id":3,"username":"dcgatan78#gmail.com","policyno":"V38998933","fname":"Donald","mobile":"0501234567","email":"dcgatan#gmail.com","address":"MetDubai","amount":334.34,"datetimestamp":1472862939000},{"id":4,"username":"dcgatan#yahoo.com","policyno":"V34342323","fname":"Snoopy","mobile":"0501234567","email":"dcgatan#yahoo.com","address":"Metlife Dafza Dubai","amount":883.43,"datetimestamp":1472916463000}]
My http://localhost:8080/myview is not working because when I tried the below code with Array value it works. How to call the http instead of putting static values in the Array?
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class PeopleService {
people: Array<any> = [{"id":1,"username":"donald#yahoo.com","policyno":"V121293031","fname":"Donald","mobile":"0504735250","email":"dcgatan#gmail.com","address":"Dafza Dubai","amount":800.98,"datetimestamp":1472861297000},{"id":3,"username":"dcgatan78#gmail.com","policyno":"V38998933","fname":"Donald","mobile":"0501234567","email":"dcgatan#gmail.com","address":"MetLife Dubai","amount":334.34,"datetimestamp":1472862939000}];
constructor(private http: Http) {}
load(){
if (this.people) {
return Promise.resolve(this.people);
}
return new Promise(resolve => {
this.http.get('http://localhost:8080/myview')
.map((res)=>res.json())
.subscribe((data)=>{
this.setPeople(data);
resolve(this.people);
});
});
}// end load function
setPeople(data) {
if (data) {
for (let id of Object.keys(data)) {
let item = data[id];
item.id = id;
this.people.push(item);
}
}
}
}
Your call to /myview would be returning incorrect json. It must be having HTML elements. Performing res.json() extracts data from _body of the response, if it's valid. But in your case it is throwing an error.