I have a search method for domains that returns whether or not it can be registered. I am having trouble accessing the 'status' string in the returned JSON body.
Here is my AngularJS code for accessing the API:
hosting.searchDomain = function() {
var domain = hosting.domain;
var tld = hosting.tld;
var url = apUrl + 'api/domains/available.json?auth-userid='+ resellerId +'&api-key='+ key +'&domain-name='+ domain +'&tlds='+ tld +'';
$http({
method: 'GET',
url: url,
}).then(function successCallback(response) {
var data = response.data;
console.log(data);
hosting.searchResults = data;
}, function errorCallback(response) {
console.log('Eror: ', response);
});
}
And this returns something like this when you search mydomains.com:
{"mydomains.com":{"status":"regthroughothers","classkey":"domcno"}}
I don't understand how I would access the status string?
Try:
console.log(data["mydomains.com"].status);
See it working here:
https://jsfiddle.net/n6jqbcp9/
First, convert the JSON to a JavaScript object.
data = JSON.parse(data);
Access the property status:
status = data["mydomains.com"]["status"]
Related
I have service to get some data from API and serve them to application.
Simple function like this:
getEnvironmentStatus() {
var _this = this;
var req = {
method: "GET",
url: "/api/system/hosting",
headers: {},
data: {}
}
return _this.$http(req);
}
In some other place I have:
determineHostingEnv() {
var _this = this;
this.$env.getEnvironmentStatus()
.then(function(response){
_this.EnvHositng = response.data.cloud_hosted;
}, function(error) {
});
}
If I need the same information in other place (other controller), I would need to call api again.
How can I make getEnvironmentStatus() function to call API only once and store data in local variable, so it can serve that variable next time it is asked for it, instead of calling API?
Also, what if that value will get requested a few times before the first API will return value? Can I prevent calling that API a few times?
One can cache the promise:
httpPromiseCache = null;
getEnvironmentStatus() {
var _this = this;
var req = {
method: "GET",
url: "/api/system/hosting",
headers: {},
data: {}
}
if (!_this.httpPromiseCache) _this.httpPromiseCache = _this.$http(req);
return _this.httpPromiseCache;
}
The service will only execute the HTTP request once.
I'm trying to learn ExpressJS and I'm having trouble getting IP address from an Express route to display in the browser via Angular controller.
I'm using 2 Nodejs modules (request-ip and geoip2) to get the IP and then lookup geolocation data for that IP. Then trying to use Angular to display the geolocation data in the browser using an Angular $http get call.
My Express route for the IP:
// get IP address
router.get('/ip', function (req, res, next) {
console.log('requestIP is ' + ip);
// geolocation
geoip2.lookupSimple(ip, function(error, result) {
if (error) {
//return res.status(400).json({error: 'Something happened'});//default
return res.sendStatus(400).json({error: 'Something happened'});
}
else if (result) {
return res.send(result);
}
});
});
And my AngularJS controller code:
function MainController($http) {
var vm = this;
vm.message = 'Hello World';
vm.location = '';
vm.getLocation = function() {
$http({
method: 'GET',
url: 'localhost:8000/ip'
}).then(function (result) {
console.log(result);
return vm.location = result;
});
};
};
The Hello World message displays but not the location...? I can also go to localhost:8000/ip and see the JSON result. The result doesn't appear in Chrome's console either. The result is a json object like this:
{"country":"US","continent":"NA","postal":"98296","city":"Snohomish","location":{"accuracy_radius":20,"latitude":47.8519,"longitude":-122.0921,"metro_code":819,"time_zone":"America/Los_Angeles"},"subdivision":"WA"}
I'm not sure why the Hello Word displays and the location doesn't when it seems that I have everything configured correctly... so obviously I'm doing something wrong that I don't see...?
You have initialised 'vm.location' as a string when in fact it is a JSON object.
vm.location = {};
You need to adjust the url paramater in your request to:
url: '/ip'
As you are sending back JSON from Express.js, you should change your response line to:
return res.json(result);
Do you call vm.getLocation() somewhere in your code after this?
The data you need is under result.data from the response object.
Also in order to display the data in the html you have to specify which property to display from the vm.location object (vm.location.country, vm.location.city etc..).
From angular docs about $http:
The response object has these properties:
data – {string|Object} – The response body transformed with the transform functions.
status – {number} – HTTP status code of the response.
headers – {function([headerName])} – Header getter function.
config – {Object} – The configuration object that was used to generate the request.
statusText – {string} – HTTP status text of the response.
Is this express js and angular hosted on the same port? If so please replace your
$http({
method: 'GET',
url: 'localhost:8000/ip'
}).then(function (result) {
console.log(result);
return vm.location = result;
});
with
$http({
method: 'GET',
url: '/ip'
}).then(function (result) {
console.log(result);
return vm.location = result;
});
It may be considered as CORS call and you have it probably disabled.
You can also specify second function to then (look code below) and see if error callback is called.
$http({
method: 'GET',
url: '/ip'
}).then(function (result) {
console.log(result);
return vm.location = result;
}, function (error) {
console.log(error);
});
In Angular controller, I have some codes like :
$http.save('api/purchases').$promise.then(function(response) {
var location = response.headers('location'); // to retrieve the location in response header
})
in jasmine's unit test,
it('..', function(){
$httpBackend.expectPost('api/purchase').respond(201, {}, {location: 'xxx'});
// when run the test, it reports an error with 'undefined is not a constructor' (evaluting response.headers('location'))
})
How can i test the response.headers('location')?
The Angular docs seem to indicate that respond needs statusText when given headers (as in it is not optional and is required when passing in headers)
function([status,] data[, headers, statusText])
You should be able to pass some text for a 201 like so
$httpBackend.expectPost('api/purchase').respond(201, {}, {location: 'xxx'}, 'Created');
use transformResponse in $resource action
var resource = $resource('api/purchase', {}, {
get: {
method: 'GET',
transformResponse: function(data, headers) {
var response = {};
response.data = data;
response.headers = headers();
return response;
}
}
}
to retrieve 'location':
resource.get().$promise.then(function(response){
var location = response.headers.location; // 'headers' has been put into response object above
})
then test can run normally.
I encountered a bug in a square-connect API wrapper for node, and I made a fiddle to recreate the issue. I noticed my code wasn't working, in the sense that angular {{}} stuff isn't showing up. What's wrong with it?
the only thing I'm trying to do is have the raw JSON object (preferably {{res}}, but it doesn't matter really) shown below the create button. I am just trying to demonstrate to the author of a library that my object and data is valid, and that a bug is in his library, not my implementation.
var httpRequest = $http({
method: 'POST',
url: '/echo/json/',
data: item
}).success(function(data, status) {
$scope.res = data;
}).failure(function(data, status){
$scope.res = data+status;
});
data is not being returned from jsfiddle's ECHO.
http://jsfiddle.net/efjytg6r/2/
You were close, but since you're saving your $http in a variable, you access the methods within it using that variable. (ie: httpRequest.success / etc)
Also it's .error() not .failure()
var httpRequest = $http({
method: 'POST',
url: '/echo/json/',
data: item
});
httpRequest.success(function(data, status) {
$scope.res = data;
});
httpRequest.error(function(data, status){
$scope.res = data+status;
});
jsFiddle is finicy with it's echo AJAX examples. You need to format what you send to them correctly with json, have it stringified as well as use jQuery's $.param (since angular doesn't do POST like you're used to with jQuery).
I included jQuery to the fiddle below.
I formatted the data being sent differently
I moved your {{ res }} inside of the controller area (you had it outside, which means it won't compute)
I added | json filter to {{ res | json }}
Updated jsFiddle
// the wacky format you need if you want to do fake $http to jsFiddle
// case in point, if you're trying to DEMO this, I wouldn't even bother, since it won't look like this when you actually use this within your application
var data = $.param({
json: JSON.stringify({
item
})
});
$http.post("/echo/json/", data)
.success(function(data, status) {
$scope.res = data;
}).error(function (status) {
});
Here is an example using $httpParamSerializer and a delay.
angular.module('myApp',[]);
angular.module('myApp').controller('myVm',
function($scope,$http,$httpParamSerializer) {
var vm = $scope;
var xitem = {a:"1",b:"2"};
var data = $httpParamSerializer({
json: xitem,
delay: 6
});
console.log("Posting xitem");
vm.p = $http.post('/echo/json/',data);
vm.p.then (function(response) {
console.log(response);
console.log(response.data)
})
});
how do i encode the keyword that get sent to the server and then decode it?
I can't search for keywords containing chars like .? or / at the moment.
The code displaying is wrong because endpoint returns a object.
self.search = function (keyword) {
var endpoint = $location.path(baseEndpoint + "search/").search(keyword),
deferred = $q.defer();
$http.get(HttpRequestUrlHelper.ensureUniqueRequestUrl(endpoint), {
}).success(function (response) {
deferred.resolve(response);
}).error(function (error) {
deferred.reject(error);
});
return deferred.promise;
}
If i use encodeURIComponent() my url is encoded but my controller isn't hit:
request url => /todo/search/Leka%20med%20barnen.?UniqueKey=1404655031784 angular.js:9159
GET http://localhost:49195/todo/search/Leka%20med%20barnen.?UniqueKey=1404655031784 404 (Not Found)
You can use the escape function: http://www.w3schools.com/jsref/jsref_escape.asp
Ended up making a query string instead:
var endpoint = baseEndpoint + "search?keyword=" + keyword,