- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-18-2018 05:18 AM
I am trying to use the $http service to retrieve response object from the HERE Maps Geocoder Autocomplete API. I am using a custom widget for this purpose. In the client controller script I have tried using the $http.get() method to retrieve the response object. Here is the client controller code:
$scope.getLocation = function(val) {
$http.get('//autocomplete.geocoder.api.here.com/6.2/suggest.json?app_id=[app_id]&app_code=[app_code]', {
params: {
query:val
}
}).then(function(response){
console.log(response);
})
};
The variable val here is actually fetching the input from the typeahead search bar that I have used in the html. Here is the html side code:
<input name="searchBar" type="text" ng-model="searchFood"
placeholder="search around your locality..."
uib-typeahead="loc for loc in getLocation($viewValue)"
typeahead-loading="loadingLocations"
typeahead-no-results="noResults" class="form-control">
The problem is this piece of code is throwing error response as follows: XMLHttpRequest cannot load https://autocomplete.geocoder.api.here.com/6.2/suggest.json?app_id=[app_id]&app_code=[app_code]&quer.... Response for preflight has invalid HTTP status code 405
I tried testing the REST API endpoint by creating a separate REST message and executing the same GET method and it returned the correct response there but whenever I am trying to use the $http.get() service in the widget it is throwing me this error.
Thanks in advance for the help!
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-19-2018 04:42 AM
Okay, not being able to do this client side was bugging me too. So I dug deeper.
It seems that some common OPTIONS headers are sent by default. In order to override the OPTIONS, one of the AngularJS default headers need to be blanked out. Also you'll find that doing this will disrupt the "get" method from adding the params automatically. But with a little bit of restructuring this can work client side.
This time I added a little bit more structure to the example.
HTML:
<div class="form-group">
<label for="query">Query</label>
<input name="query" class="form-control" ng-model="data.query" ng-model-options='{ debounce: 1000 }' ng-change="doClientSide()">
<ul class="list-group">
<li class="list-group-item" ng-repeat="suggestion in c.results.suggestions" ng-bind-html="suggestion.label">
</ul>
</div>
Client Controller:
$http.defaults.headers.common = {}; //This is the part to resolve the preflight issue
$scope.doClientSide = function(){
$http.get(
'//autocomplete.geocoder.api.here.com/6.2/suggest.json?app_id=[app_id]&app_code=[app_code]&beginHighlight=<mark>&endHighlight=</mark>&query='+ c.data.query //tacked on the query/param here
).then(function(response){
c.results = response.data;
})
}
Result:
No more preflight error. Hope that helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-18-2018 05:20 PM
Usually the preflight response is due to a CORS issue where the API endpoint isn't allowing Cross-origin resource sharing when sent from client side. But when you send the same thing to the endpoint from server-side it works.
If you have it working already using an Outbound REST API in ServiceNow you can still call it within the widget. Here's a mock up
HTML:
<div>
<input class="form-control" ng-model="data.query" ng-blur="getAutoComplete()">
<div><pre>{{ data.responseBody | json}}</pre></div>
</div>
Server side:
(fucntion(){
if(input){
try {
var r = new sn_ws.RESTMessageV2('here', 'Autocompelete');
r.setStringParameterNoEscape('query', input.query);
var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
data.responseBody = JSON.parse(responseBody);
}
catch(ex) {
var message = ex.getMessage();
}
}
})();
Client Controller:
function($scope){
var c = this;
$scope.getAutoComplete = function (){
$scope.server.update()
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-19-2018 04:42 AM
Okay, not being able to do this client side was bugging me too. So I dug deeper.
It seems that some common OPTIONS headers are sent by default. In order to override the OPTIONS, one of the AngularJS default headers need to be blanked out. Also you'll find that doing this will disrupt the "get" method from adding the params automatically. But with a little bit of restructuring this can work client side.
This time I added a little bit more structure to the example.
HTML:
<div class="form-group">
<label for="query">Query</label>
<input name="query" class="form-control" ng-model="data.query" ng-model-options='{ debounce: 1000 }' ng-change="doClientSide()">
<ul class="list-group">
<li class="list-group-item" ng-repeat="suggestion in c.results.suggestions" ng-bind-html="suggestion.label">
</ul>
</div>
Client Controller:
$http.defaults.headers.common = {}; //This is the part to resolve the preflight issue
$scope.doClientSide = function(){
$http.get(
'//autocomplete.geocoder.api.here.com/6.2/suggest.json?app_id=[app_id]&app_code=[app_code]&beginHighlight=<mark>&endHighlight=</mark>&query='+ c.data.query //tacked on the query/param here
).then(function(response){
c.results = response.data;
})
}
Result:
No more preflight error. Hope that helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-20-2018 12:26 AM
Thanks a ton! I was able to call the REST message from the server side in the usual way but not being able to do from the client side by using the very basic $http service was driving me nuts! Your post just solved that problem 🙂 Thanks a ton!