Angular.js prepends base path to absolute path URL - angularjs

I'm absolutely new to angular.js, so I'm sorry for a such stupid question. But maybe it would help a little bit to other beginers.
I'm learning from a sample project created by someone else, but I'm using a local IIS (instead of IIS Express or VS dev. server). So my base path is http://localhost/SampleProject
The sample project contains this $http.get
$http.get('https://maps.googleapis.com/maps/api/geocode/json',
{
params: params,
headers: { 'Accept-Language': 'en' }
}
)
This works on base URL like "http://localhost:1234", but in my case I get
Failed to load resource: the server responded with a status of 400 (Bad Request)
because request URL is
http://localhost/SampleProject/https://maps.googleapis.com/maps/api/geocode/json?sensor=false
Can anyone tell me why is angular.js prepending base url even if absolute path URL is used?
Thanks,
Tom

Nothing related to $http
From 1.3, Angular does not allow global variable controller.
Here is the working version:
http://plnkr.co/edit/zGj4Ayy8NIplUva86NP6?p=preview
var app = angular.module('myApp', []);
app.controller('customersController',
function($scope,$http) {
var params = { address: "Zlin, Czech Republic", sensor: false };
$http.get("https://maps.googleapis.com/maps/api/geocode/json", {
params: params,
headers: { 'Accept-Language': 'en' }
}).success(function(response) {
$scope.names = response;
});
});

I've solved this issue. It was caused by wrong default URL handling.
I had to add
if (config.url.indexOf('http') !== 0 && config.url.indexOf('//' !== 0))
line into app.js file:
app.config(["$httpProvider", function ($httpProvider) {
$httpProvider.interceptors.push('middleware');
}]);
app.factory('middleware', ['__baseUrl',
function (__baseUrl) {
return {
request: function (config) {
// handle absolute URL request
if (config.url.indexOf('http') !== 0 && config.url.indexOf('//' !== 0))
{
config.url = __baseUrl + config.url
}
return config;
}
};
}]);

Related

$http:GET Invalid basic header. No credentials provided

When i tried to access star wars API using $http method . am getting 403 response with message "Invalid basic header. No credentials provided" what am missing here?
$http({
method : 'GET',
url : 'https://swapi.co/api/people/'
}).then(function(success) {
var data = JSON.parse(body);
var result = data.result.filter(function each(r) {
return username == r.name && password == r.birth_year;
});
}, function(error) {
alert('not logged::' + eror)
});
Could you please someone help me to find the issue?
You are using wrongly the data returned by the get call.
You don't need to parse it to JSON, it's already a JSON.
Here's a plunker with a call to the API working. Hope it helps you
https://plnkr.co/edit/WKQfqc7wxmBJIjYUyZKe
angular.module('myApp', []).controller('myAppController', function($http, $scope) {
$scope.callApi = function() {
$http.get('https://swapi.co/api/people/').then(function(result) {
$scope.characters = result.data.results;
}, function(error) {
alert('not logged::' + error)
});
}
});

Send data by post from AngularJs to Django

I want to send data from AngularJS to the back end (Django) via Http request.
I tried many ways but I keep not getting the sent data when receiving the request in django.
Before I paste my code, I just have changed the configurations in AngularJS in my project as the following
var myApp = angular.module('myApp',[]).config(['$httpProvider', '$interpolateProvider', function ($httpProvider, $interpolateProvider) {
$interpolateProvider.startSymbol('{/');
$interpolateProvider.endSymbol('/}');
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';}]);
The urls:
urlpatterns = [
url(r'^save_comment/', views.save_comment, name='save_comment'),]
Sending Https POST in Angular:
$scope.submit_comment = function () {
$http({
method: "POST",
url: 'save_comment',
data: $.param({
'fish_id' : "1"
})
}).success(function (response) {
console.log(response.result);
}).error(function () {
console.log("failed")
}); }
Receiving the request in the Views
def save_comment(request):
data = request.POST.get('fish_id')
return JsonResponse({'result': data}, content_type="application/json", safe=False)
But I didn't get any result. the console gave me this error:
POST http://127.0.0.1:8000/brain_browser/save_comment 500 (Internal
Server Error)
So what should I do to send Post data from Angular to Django?
Thank in a dvance.
Not an answer but you can debug yourself. Add this to settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
Your url: 'save_comment' seems to be missing a slash at the beginning, since your url expects http://127.0.0.1:8000/save_comment/ but because of the missing slash you are sending http://127.0.0.1:8000/brain_browser/save_comment.
So change the url in your Javascript to url: '/save_comment/'
Edit: #bobleujr's answer could also fix the problem if csrf tokens are the problem. In my personal Angular/Django project I simply put this at the very top of my javascript:
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
2nd Edit: This should be the solution
In your views, do this instead of data = request.POST.get('fish_id'):
body_unicode = request.body.decode('utf-8')
data = json.loads(body_unicode)
# Work with "data" from now on, i.e:
print(data["fish_id"])
This is because request.body (Your parameters) is a byte string, and json.loads does not accept byte strings.
Also make sure you have json imported in your views at the very top like so:
import json

Error 405 & 401 open weather map API Angularjs

trying to call data through openweathermap api
if I call it through 'GET'method.there is
405 (Method Not Allowed)
var req = {
method: 'GET',
url: 'http://api.openweathermap.org/data/2.5/forecast/daily?APPID=' + ApiKey + '&q=London,us',
headers: {
'x-api-key': ApiKey
}
}
$http(req)
.then(function (data) {
console.log(data);
}, function (err) {
console.log(err);
});
#faisal
I ran into this error today, and after some debugging, I realized that it was because I had $httpProvider.defaults.headers.common['X-Requested-With'] = 'HttpRequest'; in my config file. I just disabled CORS for convenience and solved the problem.
This answer is what helped me: Disable CORS in angularJS
Use the params property to encode the search parameters:
var req = {
method: 'GET',
//url: 'http://api.openweathermap.org/data/2.5/forecast/daily?APPID=' + ApiKey + '&q=London,us',
url: 'http://api.openweathermap.org/data/2.5/forecast/daily',
params: { appid: ApiKey, q: 'London,us' }
}
The problem is likely that the &q=London,us is illegal. The comma character needs to be percent-encoded to q=London%2Cus. Use the params property to properly encode the parameters.
Update
I tested it with my APPID (which I am not going to publish) and it worked.
Here is my DEMO on PLNKR with the APPID removed.

CORS and Angular $http GET to Google Places API

New to angular, trying to setup a very simple application using the Google Maps / Places API.
I can successfully use the geolocation service with:
.controller('MainCtrl', [
'$scope',
'$http',
function($scope, $http){
$scope.userLocation = [];
$scope.currentLocation = function() {
$http({
method: 'GET',
url: 'https://www.googleapis.com/geolocation/v1/geolocate?key=xxx'
}).then(function successCallback(response) {
$scope.userLocation.push(response);
});
}
}])
Problem:
When I try a similar GET request to their Places API - I get CORS errors:
XMLHttpRequest cannot load https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=36.23…5.1458888&type=bar&key=xxx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://0.0.0.0:3000' is therefore not allowed access.
Question: Am I able to make these types of requests from Angular or do I need to setup the backend to make that call instead?
I tried using JSONP as the method, which passed the CORS issue, but then I have the problem of not being able to access the data. Not sure if it's invalid JSON... but it says Unexpected identifier :, and when I view the source it looks like perfectly fine data to me:
{
"html_attributions" : [],
"results" : [
{
"geometry" : {
"location" : {
"lat" : 36.2388477,
"lng" : -115.1540073
},
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
"id" : "578bfba1f17b0c5fbdafd5b71600b50d3e95c1ca",
"name" : "Ruby Tuesday",
"opening_hours" : {
"open_now" : true,
"weekday_text" : []
},
You can use Places API on client side via the library included in Google Maps JavaScript API.
Please refer to this page to figure out how it works:
https://developers.google.com/maps/documentation/javascript/places
Otherwise, you have to create your backend server to send requests to Google and pass response to your client side code.
Hope it helps!
After research I found the below solution. It worked on angular 11.
Some google get api gives CORS issues so to resolve that you need to install below npm package
npm install axios
In the sevice.ts file
const axios = require('axios');
getTimeZone(latitude: any, longitude: any): any {
console.log("lat", latitude);
const url1 =
`https://maps.googleapis.com/maps/api/timezone/json?location=` +
latitude +
"," +
longitude +
`&timestamp=1331161200&key=` +
this.googleApiKey;
const config = {
method: "get",
url: url1,
headers: {},
};
return new Observable<any>((observer) => {
axios(config)
.then(function (response: any): void {
observer.next(response.data);
// return response.data;
})
.catch(function (error: any): void {
observer.next(error);
});
});
}
in component.ts file
getTimezoneVal(lat: any, long: any): void {
this.lat = lat;
this.long = long;
this.googleAddressService.getTimeZone(lat, long).subscribe(
(res: any) => {
console.log("res", res);
})
}
In component file you will get response and CORS issue will get resolved....
Thanks....
Vikas Anand
I think JSONP may work in this situation, Jsonp helps for cross domain issues.

angular-resource.js encodeUriSegment Issue

I have an issue querying restful resources when the resource uri has several subpaths :
Example :
.factory('SomeFactory', function ($resource) {
return $resource('/path/subPath/otherSubPath/:id', {}, {
show: { method: 'GET', params: { id: '#id' } }
})
}) ;
When I invoke SomeFactory.show in a controller I get the error
the server responded with a status of 400 (Bad Request)
This is because the browser is looking for the uri :
http://server/path/subPath%2FotherSubPat/id
Notice the %2F replacing the / (slash) in the uri , I have tried many tricks in javascript to make this work ; But the only solution was to add the following last line replace(/%2F/gi, '/'); in angular-resource.js encodeUriSegment method .
Please tell me if this approach is correct .
function encodeUriSegment(val) {
return encodeUriQuery(val, true).
replace(/%26/gi, '&').
replace(/%3D/gi, '=').
replace(/%2B/gi, '+').
replace(/%2F/gi, '/');
}
Thanks .
it seems like you have already bumped into this issue opened on github:
https://github.com/angular/angular.js/issues/1388#issue-6979382
where the approach you've taken is suggested. As far as I am concerned, as I had the same issue as you, I preferred to have multiple services (one for each subpath) rather than modifying angular-resource.js - I prefer to not modify core lib files as any updates will wipe those changes.
Hopefully a flag to se the uri encoding will be added to Angular to solve this problem.
You can use http interceptor:
module.constant("interceptULRS",
[new RegExp('.+/path/.*')]);
module.config(['$httpProvider', 'interceptULRS', function($httpProvider, interceptULRS) {
var ENCODED_SLASH = new RegExp("%2F", 'g');
$httpProvider.interceptors.push(function ($q) {
return {
'request': function (config) {
var url = config.url;
for (var i = 0; i < interceptULRS.length; i++) {
var regex = interceptULRS[i];
if (url.match(regex)) {
url = url.replace(ENCODED_SLASH, "/");
// end there is only one matching url
break;
}
}
config.url = url;
return config || $q.when(config);
}
};
});
}]);
Keep in mind that it will intercept all URLs.
Building off of #Pavol I think you can pare the request function down to
var ENCODED_SLASH = new RegExp("%2F", 'g');
var request = function (config) {
var matches = config.url.match(ENCODED_SLASH);
if (matches && matches.length) {
config.url = config.url.replace(ENCODED_SLASH, "/");
}
return config || $q.when(config);
};
if you don't need ENCODED_SLASH elsewhere, and don't care where the "%2F"s are in the url.
As I work more and more with the angular-resource I'm finding using and understanding the $httpProvider.interceptors to be more important.

Resources