AngularJS unexpected request ngmock

97 Views Asked by At

I get an unexpected request error on GET /#/car/view/0 where 0 is the :carId.

It's for a basic angular crud application on a ngMock backend. The $httpBackend.whenGET(carUrl) works and gives back a list of all cars. The addCar() also works.

I can't figure out what I'm doing wrong with getting the detailed view

I need some help with getting the correct url's and to get a detailed view by id. Obviously the code below works because the url's are static but I can't find the right way to get the url with the ID variable.

thecode:

App.js

routing:

.when('/car', {
        templateUrl: 'pages/car/car.html'

    })
    .when('/car/view/:carId', {
        templateUrl: 'pages/car/carView.html',
        controller: 'carViewCtrl',
        controllerAs: 'ctrl'
    })
    .when('/car/addCar', {
        templateUrl: 'pages/car/carAdd.html'
    })

app.run: this is where my mock backend is defined

window.app.run(function($httpBackend) {
var cars = [
  {
    id: 0, 
    name: ‘car0’, 
    address: 'adress0', 
    tel: 'tel0', 
    email: 'email0'}, 
  {
    id: 1, 
    name: ‘car1’, 
    address: 'adress1', 
    tel: 'tel1', 
    email: 'email1'
  }];

var carUrl = “/#/car”;

//this works and gives back the list of all cars
$httpBackend.whenGET(carUrl).respond(function(method,url,data) {
     return [200, cars, {}];
});

//this is where it goes wrong I think
$httpBackend.whenGET(‘/#/car/view/:carId').respond(function(method, url, data){
     return [200, cars, {} ];
});

});

CarService.js

window.app.service(‘CarService', ['HTTPService', '$q', '$http', function (HTTPService, $q, $http) {
'use strict';

cars = [];
this.showDetails = function (carId){
    var deferred = $q.defer();

    HTTPService.get('/car/view/' + carId).then(function resolve(response){

    deferred.resolve(response.data);

    }, function reject(response){
        deferred.reject(response);
    });

    return deferred.promise;
};

carView.js

window.app.controller(‘carViewCtrl', ['$scope', '$routeParams', '$location', ‘CarService', function ($scope, $routeParams, $location, CarService) {
'use strict';

$scope.carId = $routeParams.carId;
initCar($scope.carId);

function initCar(carId) {
    CarService.showDetails(carId).then(function success(car) {
    $scope.car = car;
    }, function error(response) {

    });
   }
 }]);

carList.html

<tr ng-repeat=“car in cars track by $index">
        <td>{{$index}}</td>
        <td><a href=“/#/car/view/{{car.id}}”>{{car.id}}</a></td>
        <td>{{car.name}}</td>
        <td>edit</td>
</tr>
1

There are 1 best solutions below

3
On BEST ANSWER

The url for $httpBackend.whenGET is either a string, regex or a function the returns true or false.

So you are only providing a string which won't match, you need to supply a regex that matches such as /\/#\/car\/view\/(.+)/

To access the data you capture with the regex you need to specify params that line up with your capture groups

$httpBackend.whenGET(/\/#\/car\/view\/(.+)/, undefined, undefined, 
    ['carID'])
.respond(function(method, url, data, headers, params) {
     return [200, {myReponse: 'this worked'}
});

To go into more details, from the docs:

Regex parameter matching If an expectation or definition uses a regex to match the URL, you can provide an array of keys via a params argument. The index of each key in the array will match the index of a group in the regex.

The params object in the callback will now have properties with these keys, which hold the value of the corresponding group in the regex.

This also applies to the when and expect shortcut methods.

What this means is that for the expect or when (such as whenGET) methods you can use a regular expression to match a url. Then for each capture group, which are whats inside of a ( ) block, you can store it in a variable which will be passed to your callback in the params object.

So, for a working example take a look at this plunker. As a side note, it seems that older versions of angular-mocks don't support this functionality as I got an error that carId was not defined for angular v1.2.23