Environment
I have a frontend built using Angular2 which communicates with an API built using Slim PHP Framework v4.
Within the Angular frontend, a user can enter text into a form and submit it, then receive a response from the API.
The Angular project makes a request to the URL /api/{text}
.
As far as I am aware, there is no way to access arguments supplied via, for example, /api?text={text}
in Slim v4 and so I am unable to utilise Angular’s HttpParams
feature. For this reason, the URL is passed to Angular’s HttpClient
directly. i.e.
let text = 'Some random text / with special characters .';
let myObservable: Observable<MyResponseObject[]>;
myObservable = this.http.get<MyResponseObject[]>(
'http://my.domain.name/api/' + text
).pipe(catchError(this.handleError));
Problem
I have read that certain characters are encoded, then decoded again by Angular prior to submitting a request (i.e. ,
/
,.
). For this reason, the value of the text
variable in the above example is invalid.
One solution is to manually create a regex statement and use it to encode the string prior to submitting a request, then decode the string within the API.
I would like to avoid this and so I am wondering if one of two things is possible:
-
Is there any Javascript, Typescript or Angular feature for encoding strings, as described, for use within a URI?
-
Is there any way that I can access the value of arguments supplied with the format
?text={text}
from a GET request within Slim version 4?
EDIT:
I’m also using custom provider within Angular to attach an auth token as a URL parameter in the format ?auth=[my_token_here]
. The token is attached to every request sent by Angular. The custom provider uses the following code to attach the parameter:
intercept(req: HttpRequest<any>, next: HttpHandler) {
return this.authService.user.pipe(take(1), exhaustMap(user => {
if(!user) {
return next.handle(req);
}
const modifiedReq = req.clone({
params: new HttpParams().set('auth', user.token)
});
return next.handle(modifiedReq);
}));
}
I’ve worked out how to read the value of ‘auth’ from the Slim API. However, when I modify the get request to add the text
variable as a parameter, the parameter is never submitted and the Slim API still only sees the auth
parameter. The modified code is as follows:
myObservable = this.http.get<MyResponseObject[]>(
'http://localhost:8080/ngrams/', {
params: new HttpParams().set('text', text)
}).pipe(catchError(this.handleError));
So here there are no errors, but the ‘text’ parameter is never attached to the URL (I can see only the auth parameter when checking the browser’s network tab when I submit the request).
I’m an Angular noob so this logic may be flawed, but the above code for authentication was copied from a tutorial. My thinking is that maybe assigning new HttpParams()
in the auth provider is overriding the parameters I set for the get request.
When I create the same request manually or using Postman, so the URL in my local environment is http://localhost:8080/api/?text=some text goes here
, then I can successfully retrieve the parameter using the $req->getQueryParams()
method.
2
Answers
As per Nima's answer, the values were being read correctly by the Slim API when using
getQueryParams()
. The issue was that the parameters were not being sent in the first place.The problem was that my authentication service was assigning a new
HttpParams
object to http requests, where it should have been adding an auth token to the existing set of parameters.This issue was solved by updating the
intercept()
method mentioned in the question, so that theauth
token is attached to the request's existingparams
property:According to Slim 4 documentation:
Here is an example:
If you visit
/api?text=special chars %3A%20 %2F %3F %25 %26 ^ %23
the result is: