AngularJs $httpbackend.whenPOST regular expression not working - angularjs

am getting an error
Error: Unexpected request: POST data/employee/1
No more request expected
Am using angular-mocks, angular-ui-route in my app.config i've got my $stateProvider routes and my mocks the main one with the issue being the one below:
$httpBackend.whenPOST(/data\/employee\/(\d+)/, {}, {},['id']).respond(function(method, url, data, headers, params){
console.log('Received these data:', method, url, data, headers, params);
return [200, {}, {}]
});
Calling via controller:
app.controller("employeeController", ['$scope','$http', "$state", "$stateParams", function($scope, $http, $state, $stateParams){
$http.post("data/employee/1").then(function(response){
})
})
What might be the issue?

In order for the mock $httpBackend.whenPOST(url, [data], [headers], [keys]) to work optional parameters data and header need to be declared as undefined where they are not used and not just as empty objects {}.

Related

Get "initially loaded" (not AJAX call) Response Headers with AngularJS

In looking at How to read response headers in angularjs?, I see answers that involve making an http/ajax request after the page loads then getting the response headers.
I have an angularJS app that needs to render the page (immediately when it loads, not after) using some JSON in a custom response header key that I've added on my python backend.
Is there non-hacky a way to do this? Or is the very attempt at rendering a web page using AngularJS to parse response headers a hack in itself?
My headers look like this (I'm trying to get myjson) :
Keep-Alive:timeout=1, max=100
myjson:{"key2": "value2", "key1": "value1"}
Server:Apache
I think this is what you are aiming for, using $http and ngRoute. Forgive me if I'm misunderstanding. It's just loading data about this question via SO's API. If you click Load Data, you'll see the headers from SO on that page..
var app = angular.module('plunker',['ngRoute']);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/home', {
template: '<h1>Test 1</h1>',
controller: 'HomeCtrl'
}).
when('/loaddata', {
templateUrl: 'load_data.html',
controller: 'LoadDataCtrl',
resolve: {
stackQuestion: function($http){
// We must return something with a promise. $http already does that, so does $resource.
// See: https://docs.angularjs.org/api/ng/service/$q
return $http({
method: 'GET',
url: 'https://api.stackexchange.com/2.2/questions/37491743?order=desc&sort=activity&site=stackoverflow'
})
}
}
}).
otherwise({
redirectTo: '/home'
})
}
]);
Then, in your controller:
app.controller('LoadDataCtrl',function(stackQuestion,$scope){
// now our data is here
$scope.question = stackQuestion.data;
$scope.headers = stackQuestion.headers();
});
http://plnkr.co/edit/ylOfSNqPAqjdg9rYxsbb?p=preview

ngResource - doesn't show data in browser

i have problem with ngResource.
here is my .factory
app.factory('sveKlupeServiceFactory', ['$resource',
function($resource){
return $resource('myURL/to/json', {},{
// { method: 'getKlupe', q: '*' },
query: { method: 'GET', params:{klupaId:'klupe'}, isArray:true}
});
and here is my controller
app.controller('klupeController', ['$scope', 'sveKlupeServiceFactory', function ($scope,sveKlupeServiceFactory){
$scope.klupe = sveKlupeServiceFactory.query();
}]);
and in html I have this
<tr ng-repeat="klupa in klupe">
<td>{{klupa.serial_number}}</td>
<td>{{klupa.location_id}}</td>
<td>{{klupa.type}}</td>
<td>{{klupa.last_report_dt}}</td></tr>
Problem:
in my browser I have table, but with empty row. There is no any error.
In my app I have
var app = angular.module('App', [
'ngRoute',
'ngResource']);
Can someone help me with any suggestion?
Thank you.
If you want entire table data, then there is no need to pass id as parameters in factory.Make the following changes in controller while calling factory method.
Check the response using console.log()
sveKlupeServiceFactory.query(function(res){
console.log(res);
$scope.klupe = res;
});
You should use promises to get the response.
$scope.klupe = sveKlupeServiceFactory.query();
$scope.klupe.$promise.then( function(result) { $scope.klupe = result });

How to use ngResource when server is on a different localhost?

I am building an app with Ionic and MEAN stack. My express server is running on localhost:3000 while my Ionic public code is running on localhost:8100. From my research, it seems like Ionic can run on a different IP address from the server and should just use ngResource to send $http requests.
So I have a RESTful endpoint like this in server.js
router.get('/', function(req, res){
res.json({"name":"Abdul"});
});
And on the Ionic client code I am sending in a request like this:
app.controller('mainCtrl', function($scope, $resource){
$scope.test = $resource('localhost:3000/');
$scope.test_button = function(){
console.log($scope.test);
}
});
But when I click the test_button, instead of [{"name":"Abdul"}] being logged in the console, I get the following null message:
function Resource(value) {
shallowClearAndCopy(value || {}, this);
}
Can anyone help me out on connecting the client and server?
$resource object will only create an object with having get, save, update, etc. So for calling get method of server, you need to call get method of $resource object. That method will return $promise object will provide a promise. On which you can place .then promise, in which you will get data in success function.
One more thing is, when you are returning data from the server, you are returning object in array format. So in that case you need to specify get method will return array by having isArray: true option there.
$scope.test = $resource('http://localhost:3000/', {}, {get: { isArray: true}});
$scope.test.get().$promise.then(function(data){ //success function
$scope.test = data;
},function(error){ //error function
console.log(error);
})
to make your application more better, you could move up your $resource object to service/factory to make that call reusable.
app.service('dataService', function($resource){
var resourceUrl = $resource('http://localhost:3000/', {}, {get: { isArray: true} });
this.getData = function(){
return resourceUrl.get().$promise;
};
})
Controller
app.controller('mainCtrl', function($scope, dataService){
$scope.test_button = function(){
dataService.getData().then(function(data){ //success function
$scope.test = data;
},function(error){ //error function
console.log(error);
})
}
});

difference between RestangularProvider and RestangularConfigurer

I wanted to add an interceptor to my module.
Here is the intial state:
app.config(function ($stateProvider, $urlRouterProvider,RestangularProvider) {
RestangularProvider.setBaseUrl('/app/services');
});
I modified with this:
app.config(function ($stateProvider, $urlRouterProvider, RestangularProvider, RestangularConfigurer) {
RestangularProvider.setBaseUrl('/app/services');
RestangularConfigurer.addFullRequestInterceptor(function (element, operation, route, url, headers, params, httpConfig) {
if (operation === 'get'){
console.log("RestangularProvider: call to get");
params.ts= new Date();
}
return {
element: element,
headers: headers,
params: params,
httpConfig: httpConfig
};
});
});
However, I add an error:
Error: [$injector:unpr] Unknown provider: RestangularConfigurer
So I replaced RestangularConfigurer by RestangularProvider.
But I do not clearly understand how that works, and what's happening behind the scenes.
Could you explain me that ?
First of all there is no RestangularConfigurer module. You have only Restangular and its provider RestangularProvider.
Let's start with angularjs documentation for providers.
Please esspecially read Provider Recipe as I do not duplicate it again here.
As a summary RestangularProvider is just a recipe how Restangular api should be build as you decide it in config module there is no Restangular api yet, but you have your recipe.
On the other hand Restangular will be bootstraped after your main module bootstraped, so in config there is actually no Restangular module yet.
If you still insist using Restangular instead its provider you can use it in module#run instead of module#config.

How to load data synchronously in AngularJS application

Now I know that because of the way javascript executes it is recommended that you run all remote requests as async instead of sync. While I agree with that 99% of the time, sometimes you do want to run remote request as a sync instead of a async. For example, loading session data is something I would want to do synchronically as I don't want any views to render until that data is loaded. This plunker shows the issue with loading session data asynchronically (NOTE: I am using $timeout to simulate what would happen with an async call):
http://plnkr.co/edit/bzE1XP23MkE5YKWxRYrn?p=preview
The data property does not load anything because the data is not available when it tries to get it and data2 does only because the data is available when it tries to get it. Now in this case I could just put the session variable on the scope and be done with it but that is not always the case.
Is there a better way to do sync remote calls in an angular application other than using jQuery's .ajax() method (trying to depend on jQuery as little as possible)?
If you want the session data to be loaded prior to a controller being loaded, you should included it as as resolve parameter (assuming you are using the $routeProvider).
For example:
angular.module('mymodule', ['ngResource'])
/* here's our session resource. we can call Session.get() to retrieve it. */
.factory('Session', ['$resource', function($resource) {
return $resource('/api/session.json');
}])
/* here's our controller + route definition. */
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/foo', {
controller: 'MyCtrl',
templateUrl: '/templates/foo.html',
/* the controller will not be loaded until the items
* below are all resolved! */
resolve: {
session: ['$q', 'Session', function($q, Session) {
var d = $q.defer();
Session.get(function(session) {
/* session returned successfully */
d.resolve(session);
}, function(err) {
/* session failed to load */
d.reject(err);
});
return d.promise;
}]
}
});
}])
.controller('MyCtrl', ['$scope', 'session', function($scope, session) {
/* 'session' here is the key we passed to resolve above.
* It will already be loaded and resolved before this function is called */
$scope.session = session;
}]);
Angular is hardcoded to make the requests async. To do it synchronously would take other code, whether custom or from some other library. Here is line 9269 from angular 1.0.7:
xhr.open(method, url, true);
The third param makes it asynchronous.
I would take a step back and think about how you are doing things. You could provide some loading indicator while your async request is going and easily control the loading of a view in the success callback so that it doesn't appear until the data is loaded.
A better solution is to add a response interceptor:
checkAuth = ($q, $location) ->
success = (response) ->
response
error = (response) ->
errorCode = response.status
$location.path '/login' if errorCode is 403 or errorCode is 401
# $q.reject response - no need because we are redirecting before any other promises in the chain will resolve (were breaking our future promises)
(promise) ->
promise.then success, error
$httpProvider.responseInterceptors.push checkAuth
And in your $routeProvider, or $stateProvider in my case:
.state 'user',
templateUrl: 'assets/views/user/partials/user.html'
resolve:
credentials: (checkLogIn) ->
checkLogIn.get().$promise
When checkLogIn.get()'s promise is rejected (the error handler is fired), assuming it's a 401 or 403 response (unauthenticated or unauthorized), the promise chain will be broken and the user will be "redirected" to /login.
With this method, any error calls will be channelled into the interceptor, instead of handling errors on a route-by-route basis.

Resources