I've built an API using Slim Framework.
One of my routes in Slim accept optional parameters.
Is there any way I can do this using angularjs $http.get. How can I set optional parameters in my request.
Below is my code;
$scope.getRestaurant = function () {
return $http({
method: 'get',
url: "http://api.example.co.uk/web/restaurant/details/" + $scope.id + "/" + $scope.u,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
return response.data;
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
return [];
});
}
As you can see I have $scope.id and $scope.u. I will like $scope.u to be optional. At the moment it is always passed even when it is null.
Just add it to the url if it's truthy.
var baseUrl = 'http://api.example.co.uk/web/restaurant/details/' + $scope.id;
if($scope.u) baseUrl += '/' + $scope.u;
//edited
You can use a ternary test like bellow:
$scope.getRestaurant = function () {
return $http({
method: 'get',
url: "http://api.example.co.uk/web/restaurant/details/" + $scope.id +
( $scope.u != null ) ? "/"+$scope.u : "" ,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
return response.data;
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
return [];
});
}
or create your url before you make your return
$scope.getRestaurant = function () {
var url = "http://api.example.co.uk/web/restaurant/details/" + $scope.id +
( $scope.u != null ) ? "/" +$scope.u : "" ;
return $http({
method: 'get',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
return response.data;
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
return [];
});
}
Related
I have a simple login, once user is logged in I have added a call back to run another post so that I have access to the post json to use in my system.
I think the way I have done it is correct however I am getting error
GetData is not defined
Is this the correct way to do this
JavaScript
$scope.LogIn = function () {
$http({
url: "http://www.somesite.co.uk/ccuploader/users/login",
method: "POST",
data: $.param({'username': $scope.UserName, 'password': $scope.PassWord}),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function (response) {
// success
console.log('success');
console.log("then : " + JSON.stringify(response));
GetData();
// location.href = '/cms/index.html';
}, function (response) { // optional
// failed
console.log('failed');
console.log(JSON.stringify(response));
});
};
$scope.UserData = function ($scope) {
$scope.UserName = "";
$scope.PassWord = "";
};
$scope.GetData = function () {
$http({
url: " http://www.somesite.co.uk/ccuploader/campaigns/getCampaign",
method: "POST",
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function (response) {
// success
console.log('you have received the data ');
console.log("then : " + JSON.stringify(response));
location.href = '/cms/index.html';
}, function (response) { // optional
// failed
console.log('failed');
console.log(JSON.stringify(response));
});
};
You need to update your code to be $scope.GetData();.
Currently you are using GetData() which doesn't reference the same method. In fact it is undefined as per the error message.
I have read several examples on the web and issues here on SO but I'm still missing something.
I have a service to fetch order data from my API. I want to resolve the promise inside the service. The console.log inside the service logs the correct data.
However, in my controller i get "TypeError: Cannot read property 'then' of undefined"
I thought the controller function would wait for the data to be resolved?
Service
angular.module('app')
.factory('orderService', function($http) {
// DECLARATIONS
var baseUrl = 'http://api.example.com/';
var method = 'GET';
var orderData = null;
return {
getOrderData: getOrderData
};
// IMPLEMENTATIONS
function getOrderData(ordernumber) {
// order data does not yet exist in service
if(!orderData) {
dataPromise = $http({
url: baseUrl + 'order/' + ordernumber,
method: method,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
// success
}).then(function(response) {
orderData = response.data;
console.log('Received data: ' + JSON.stringify(response.data));
return orderData;
},
// faliure
function(error) {
console.log("The request failed: " + error);
});
// order data exist in service
} else {
console.log('Data present in service: ' + orderData);
return orderData;
}
} // end: getOrderData function
}); // end: customerService
Controller
app.controller('orderController', function($scope, $stateParams, orderService) {
$scope.ordernumber = $stateParams.order;
orderService.getOrderData($scope.ordernumber)
// success
.then(function(response) {
$scope.order = response;
console.log('Controller response: ' + response);
},
// faliure
function(error) {
console.log("The request failed: " + error);
});
});
your function getOrderData doesn return a promise
function getOrderData(ordernumber) {
var deferred = $q.defer();
// order data does not yet exist in service
if(!orderData) {
dataPromise = $http({
url: baseUrl + 'order/' + ordernumber,
method: method,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
// success
}).then(function(response) {
orderData = response.data;
console.log('Received data: ' +
JSON.stringify(response.data));
deferred.resolve(orderData);
},
// faliure
function(error) {
deferred.reject(error);
console.log("The request failed: " + error);
});
// order data exist in service
} else {
console.log('Data present in service: ' + orderData);
deferred.resolve(orderData);
}
else {
deferred.reject('Not set!');
}
return deferred.promise;
} // end: getOrderData function
I have a service that returns a promise.
function GetSuggestedPeersService($http, SITE_CONFIG) {
var getSuggestedPeersService = this;
var data;
getSuggestedPeersService.getSuggestedPeersList = function() {
var baseUrl = SITE_CONFIG.baseUrl + "fetchSuggestedPeers";
var response = $http({
method : 'POST',
url : baseUrl,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
data : data
});
return response;
}
getSuggestedPeersService.setSuggestedPeers = function(suggestedPeers) {
getSuggestedPeersService.suggestedPeers = suggestedPeers;
}
getSuggestedPeersService.getSuggestedPeers = function() {
return getSuggestedPeersService.suggestedPeers;
}
}
Now I use the following in the Controller to resolve the promise:
//gets the suggested peers
var promiseSuggestedPeers = GetSuggestedPeersService.getSuggestedPeersList();
promiseSuggestedPeers.then(function (response) {
peerHealthController.GetSuggPeersShow = response.data;
GetSuggestedPeersService.setSuggestedPeers(peerHealthController.GetSuggPeersShow);
return peerHealthController.GetSuggPeersShow;
})
.catch(function (error) {
console.log("Something went terribly wrong Suggested Peers.");
});
Now my question is call this service multiple times and need to update this on other service calls as well.
What is the best way to write the controller part so as not to repeat the resolve promise every time I call the service?
It's been long time.
But I just wanted to answer this question.
The best way to design this would be to use a factory. So this will become a reusable service.
An example code can be the following:
var httpMethods = peerHealthApp.factory('HttpService',HttpService);
httpMethods.$inject = ['$http', 'SITE_CONFIG'];
function HttpService($http, SITE_CONFIG){
console.log("SITE_CONFIG from Peer Service: " + SITE_CONFIG);
var factory = {
httpGet : function(relativePath,data){
var baseUrl = SITE_CONFIG.baseUrl + relativePath;
var response = $http({
method : 'GET',
url : baseUrl,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
data : data
});
return response;
},
httpPost : function(relativePath, data){
var baseUrl = SITE_CONFIG.baseUrl + relativePath;
var response = $http({
method : 'POST',
url : baseUrl,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
data : data
});
return response;
}
};
return factory;
}
And the above can be used again and again like the following:
var data=$.param({
"url":moderatedArticleLink
});
var promiseURLMetaData = HttpService.httpPost("parseUrlMetadata", data);
promiseURLMetaData.then(function (response) {
var urlMetaData = response.data;
return urlMetaData;
})
.catch(function (error) {
console.log("Something went terribly wrong while trying to get URL Meta Data.");
});
What is the best way to write the controller part so as not to repeat the resolve promise every time I call the service?
Instead of saving the data in a service, I recommend saving the promise:
if ( !Service.get() ) {
var promise = Service.fetch();
Service.set(promise);
});
Service.get().then(function (response) {
$scope.data = response.data;
}).catch( function(errorResponse) {
console.log(errorResponse.status);
throw errorResponse;
});
By checking for the promise and only fetching if necessary, multiple controllers can share the data without caring about the order of controller instantiation. This avoids race conditions and multiple XHRs to the same resource.
I have a problem and don´t know how to solve it...
I have to authenticate a user in my IonicApp through a token based authentication. So i have to store the token inside the app, which shouldn´t be a problem...
The Problem is: How can i get the token?
Here´s my code:
// Alle Aufrufe an die REST-Api werden hier durchgeführt
var httpCall = {
async : function(method, url, header, params, data) {
// if (url != 'login') {
// header['X-Auth-Token'] = userTokenFactory.getUserToken();
// }
//console.log(header['X-Auth-Token']);
var ipurl = "IPURL";
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http({
method : method,
url : ipurl + url,
//headers : header,
params : params,
data : data,
config : {
timeout : 5000
}
}).then(function successCallback(response) {
//console.log("data:" + response.data);
//console.log("header:" + response.headers);
console.log("token:" + response.headers['X-AUTH-TOKEN']);
//console.log(response.data.token);
console.log("token" + repsonse.token);
// TRY TO READ THE X_AUTH_TOKEN HERE !!!!!!!!!!!!
return response;
}, function errorCallback(response) {
return response;
});
// Return the promise to the controller
return promise;
}
};
return httpCall;
});
And here´s a picture of the Response from the Server (from Firefox). As you can see, the X-Auth-Token is there...
here´s the x-auth-token
Thanks for the help!!
There are lot of articles are available over handling authentication in AngularJS. This article is the one perfect suitable in your case.
So you can get token from your request as,
}).then(function successCallback(response) {
console.log("data:" + response.data);
$window.sessionStorage.token = response.data.token;
return response;
}, function errorCallback(response) {
return response;
});
Now we have the token saved in sessionStorage. This token can be sent back with each request by at least three ways
1. Set header in each request:
`$http({method: 'GET', url: url, headers: {
'Authorization': 'Bearer ' + $window.sessionStorage.token}
});`
2. Setting defaults headers
`$http.defaults.headers.common['X-Auth-Token'] = 'Bearer ' + $window.sessionStorage.token;`
3. Write Interceptor:
Interceptors give ability to intercept requests before they are
handed to the server and responses before they are handed over to the
application code that initiated these requests
myApp.factory('authInterceptor', function ($rootScope, $q, $window) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($window.sessionStorage.token) {
config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
}
return config;
},
response: function (response) {
if (response.status === 401) {
// handle the case where the user is not authenticated
}
return response || $q.when(response);
}
};
});
myApp.config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
});
Refer AngularJS $http guide for detailed explanation.
As you are getting response.data null and image demonstrates that headers are being returned, I would suggest you to check if you are getting data with
response.headers(),
if then try with response.headers()["X_AUTH_TOKEN"].
I want to write a function in AngularJS that returns a value (actually it is a string). That value is returned by a http request, but async is driving me crazy.
My first attempt was:
this.readParameter = function(key) {
$http({
method: "GET",
url: "XXXXXXX",
headers: { 'Content-Type': 'application/json' }
}).then(function successCallback(response) {
return response.data;
}, function errorCallback(response) {
throw new Error("Error");
})
};
But of course it does not work because of Angular async features (response.data is undefined)
What is the way to do it? I just want to return the value (string), so I can use this function like
var a = readParameter("key1")
What you can do is define some variable with initial value outside function and on response set value inside success function instead of returning it.
Delegator pattern works great here to assign $http task to some service and use callback method for response.
Controller (Call Service for specific request) -> Service (Manage request params and other things and return factory response to Controller) -> Factory (Send request and return it to Service)
Basic example of Callback
var myVariable = '';
function myFunction (key, callback) {
$http({
method: "GET",
url: "XXXXXXX",
headers: { 'Content-Type': 'application/json' }
}).then(function successCallback(response) {
callback(response);
}, function errorCallback(response) {
throw new Error("Error");
})
};
function myCallbackFunction(response) {
myVariable = response.data; // assign value to variable
// Do some work after getting response
}
myFunction('MY_KEY', myCallbackFunction);
This is basic example to set value but instead use callback pattern from above example.
var myvariable = '';
function myFunction (key) {
$http({
method: "GET",
url: "XXXXXXX",
headers: { 'Content-Type': 'application/json' }
}).then(function successCallback(response) {
myvariable = response.data; // set data to myvariable
// Do something else on success response
}, function errorCallback(response) {
throw new Error("Error");
})
};
myFunction('MY_KEY');
Don't try to mix async and sync programming. Instead use a callback to use like
readParameter("key1", callback)
for example:
this.readParameter = function(key, callback) {
$http({
method: "GET",
url: "XXXXXXX",
headers: { 'Content-Type': 'application/json' }
}).then(function successCallback(response) {
callback(response)
}, function errorCallback(response) {
throw new Error("Error");
})
};
I resolve this by using promise:
Example :
in Service (invoicesAPIservice => invoicesapiservice.js) you use:
angular.module('app')
.service('invoicesAPIservice', function ($http) {
this.connectToAPI= function () {
return new Promise(function(resolve,reject){
var options = {
method:'GET',
url :'',
headers:{
'X-User-Agent': '....',
'Authorization': '....',
}
};
$http(options).then(function successCallback(response) {
resolve(response);
//console.log(response);
},function errorCallback(response) {
reject(response);
})
});
});
});
and in your Controller (mainCtrl=> mainCtrl.js):
angular.module('app').controller('mainCtrl', function($scope,invoicesAPIservice) {
$scope.connectToAPI=function () {
invoicesAPIservice.connectToAPI().then(function (content) {
console.log(content.statusText);
}.catch(function (err) {
//console.log(err);
alert("Server is Out");
});
}
});
And in your page : index.html:
<button ng-click="connectToAPI()"></button>
:)