I followed the directions on BreezeJS Angular Q to "Install this module", however I receive an error on the fail() callback when making a dataservice call. When using Q.js, there was no problem.
error:
Object #<Object> has no method 'fail'
dataservice call:
dataservice.getAllEntities($scope.includeName, false, i, takeNum)
.then(querySucceeded)
.fail(queryFailed);
What could be up with my setup?
I think you need to pass the fail callback as the second parameter to then,
I see Q should have that .fail() shorthand, but it's probably better to just use the standard .then() notation:
From that page:
.then(successCallback, failCallback);
So your code should be like:
dataservice.getAllEntities($scope.includeName, false, i, takeNum)
.then(querySucceeded, queryFailed);
I'm not really sure why .fail doesn't exist though..
Related
I am trying to test an AngularJS directive which uses an HTML template through a reference. Because of that, it is issuing an http request.
What I am trying to do is capturing all requests for the templates using httpBackend.whenGET("....").respond(function) to load that template from the local store.
The point is that the function is never called. I know it is matching the path because it shows no error saying the call was not expected.
By the way, I prefer to do it this way instead of using html2js.
Let's give an example.
If I set the backend.when wrong (non matching path) I get as error
Error: Unexpected request: GET resources/js/app/views/search/parts/con-search-filter/template.html
No more request expected
If I execute in my code (and I know whenGET gets called):
httpBackend.whenGET(/(.*)template.html/, undefined, undefined,
["basePath"]).respond(function(method, url, data, headers, params){
debugger;
console.log("hello");
return [200, []];
});
Then, the previous error is gone. The point is the breakpoint (debugger;) is not hit and "hello" is not printed.
I am importing angular-mocks v1.5.11 and, according to the documentation, in the line 1255, I should be able to do it
$httpBackend.whenPATCH(/\/user\/(.+)\/article\/(.+)/, undefined, undefined, ['user', 'article'])
.respond(function(method, url, data, headers, params) {
// for url of '/user/1234/article/567' params is {user: '1234', article: '567'}
});
I am using jasmine-maven-plugin version 2.2, with the chrome driver. I am executing the bdd goal.
I have figured it out what it was. Just, the requests were pending and I had to do an httpBackend.flush().
I've been trying to setup a timeout value (in milliseconds) for my $resource so that if the server doesn't respond within 10*1000 milliseconds, I want the service in my factory to return the error promise.
I have a factory with the following method:
service.getDelta = $resource(BASE_API_URL + '/delta/:inTable/:inDate',
{inTable: '#inTable', inDate: '#inDate'},
{query: {timeout: 10*1000}});
In the controller I do the following:
getDataPromises.push(remoteService.getDelta.query({inTable: "table1", inDate: clientDateLastModified}).$promise);
getDataPromises.push(remoteService.getDelta.query({inTable: "table2", inDate: clientDateLastModified}).$promise);
getDataPromises.push(remoteService.getDelta.query({inTable: "table3", inDate: clientDateLastModified}).$promise);
getDataPromises.push(remoteService.getDelta.query({inTable: "table4", inDate: clientDateLastModified}).$promise);
Then I check to ensure all are successful or handle error if one fails.
$q.all(getDataPromises).then(
function (result) {
// NOTIFY SUCCESS
},
function (error) {
// NOTIFY ERROR
});
The success in the promise has been coming through as expected. If I leave out the timeout config, I also get the error in the promise for issues like 404. But when I add the timeout, I get the following when I stringify the error object in my error callback:
{"line":13380,"column":32,"sourceURL":"file:///Users/ ... /www/lib/ionic/js/ionic.bundle.js"}
Am I misunderstanding the use of the timeout property?
I am using ionic 1.2.4 which I believe is using Angular 1.4.3.
Note: I know this use case doesn't justify use of $resource and could be done with $http, but I wanted to get to get a feel for using it since I plan to down the road for this app.
Thanks!
I'm trying to test some services that receive some modifications. Some of them are using $http service, and only one of them is populating an unknown - and a not understandable - issue.
Let me expose.
it('must reject the promise with an explanation if the required path is not found', function() {
$httpBackend.whenGET('http://localhost/testok').respond(function () {
return [200, mockedRemoteResponse, {}];
});
var promise = apiDataExtractor.extractRemoteData('ok', 'toto');
$httpBackend.flush();
});
Running this code throught Jasmine, we got this:
I do not have ANY idea of what appends. I try to change injection order, try to erase and rewrite my test, there is something here I'm missing.
Can anyone help?
The error you are seeing is probably due to a call to $http.get with undefined as the url (you might have forgotten to provide parameters to $http.get() inside apiDataExtractor.extractRemoteData?)
Try debugging your code and see what are the parameters you are giving the $http.get method.
I have a service that returns a study object as shown:
$scope.study = StudyService.studies.get({id: $routeParams.studyIdentifier});
When I print out the study object using:
console($scope.study);
I get this message on the chrome console:
Resource {$promise: Object, $resolved: false, $get: function, $save: function, $query:
function...}
So how do I read this study object. I like to be able to print its contents. For instance study has an id, and a list of cases. I like to be able to print:
console.log(study.id);
console.log(study.cases.length);
How do I accomplish this?
I assume that since you are receiving a promise as a response from your service you are using 'ngResource'. If so, then here is some documentation on using that module and how to handle the objects it returns.
https://docs.angularjs.org/api/ngResource/service/$resource
For your example though, you would need to just do the following
StudyService.studies.get({id: $routeParams.studyIdentifier}).$promise.then(function(study) {
$scope.study = study;
});
Hope this helps!
I have a Jasmine test that is coded like this:
it ("should send correct message to server to get data, and correctly set up scope when receiving it", function(){
$httpBackend.when('GET', 'https://localhost:44300/api/projectconfiguration/12').respond(fakedDtoBase);
$routeParams.projectId=fakeId; // user asks for editing project
scope.$apply(function(){
var controller=controllerToTest(); // so controller gets data when it is created
});
expect(scope.projectData).toEqual(fakedDtoBase);
});
and it kind of works, but I get the error:
Error: Unexpected request: GET views/core/main/main.html
No more request expected
at $httpBackend (C:/SVN/src/ClientApp/client/bower_components/angular-mocks/angular-mocks.js:1207:9)
at sendReq (C:/SVN/src/ClientApp/client/bower_components/angular/angular.js:7800:9)
at $http.serverRequest (C:/SVN/src/ClientApp/client/bower_components/angular/angular.js:7534:16)
(more stack trace)....
I do realise that I can mock every other call. But let's say I do not care what else my test wants to load as it may call few other things.
How I can make sure that every other requests just "happen silently", maybe offering a single dummy response for everything else?
Your test fails because a request is made which you haven't specified.
Try to add:
$httpBackend.when('GET', 'views/core/main/main.html').respond(fakedMainResponse);
Of course you should also define fakedMainResponse.
Please take a look also at the documentation (section Request Expectations vs Backend Definitions) which says:
Request expectations provide a way to make assertions about requests
made by the application and to define responses for those requests.
The test will fail if the expected requests are not made or they are
made in the wrong order.
The second paramete of $httpBackend.when is actually a RegExp. So if you provide a RegExp that will match all other requests it should work.
For those who are using the httpBackend to mock http calls in EndToEnd tests or just mocking the entire http calls for the application the solution is to add the following code in the app config section (change the regexp according your template's location):
$httpBackend.whenGET(/^\/templates\//).passThrough();
Reference: https://docs.angularjs.org/api/ngMockE2E/service/$httpBackend
Tested with angularjs 1.4 to fix similar problem while integrating ui-router
I think it's also important to notice that if you have a $digest(), your expectation should follow the $digest, like so:
_$rootScope_.$digest();
$httpBackend.when('GET', 'views/core/main/main.html').respond(fakedMainResponse);
// ...
$httpBackend.flush(); // And remember to flush at the end
you only need to add setTimeout and done property to your flush to prevent it
it('should get data in callback funcion', function (done) {
$httpBackend.whenGET(/\/my-endpoint/).respond(mockDataResponse);
apiFactory.getCurrencyFormat('en', function (res, err) {
expect(res.a).to.deep.equal(generalMock.a);
expect(res.b).to.deep.equal(generalMock.b);
});
setTimeout(function () {
done();
$httpBackend.flush();
}, 200);
});