Angular Promise Error: Cannot read property 'then' of undefined

Hi,

I’m officially stumped. Searched and examined every line and unable to get this working. I have a live Angular search field that gets its data from the factory. It’s throwing an error though: TypeError: Cannot read property ‘then’ of undefined. It’s coming from ‘.then’ in the first controller. What am I doing wrong?

var myApp = angular.module('myApp', ['ngRoute']);

myApp.config(function ($routeProvider) {

  $routeProvider

  .when('/', {
      templateUrl: 'pages/main.html',
      controller: 'vehicleController'
  })

  .when('/:firstName', {
      templateUrl: 'pages/driverData.html',
      controller: 'profileController'
  })

});


myApp.controller('vehicleController', ['$scope', 'truckData', function($scope, truckData) {
    truckData.getTrucks().then(function(trucks) { 
      $scope.vehicleSearch = trucks;
    }, function(err){ $scope.vehicleSearch = err; });
}]);


myApp.controller('profileController', ['$scope', '$routeParams', 'truckData', function($scope, $routeParams, truckData) {
    var vehicleNumber = $routeParams.vehicle;

truckData.getTruckDriver(vehicleNumber).then(function (truck) {
    $scope.model = truck
});
}]);


myApp.factory('truckData', ['$q', function ($q) {
var truckData = {}; //............................................EMPTY OBJECT
truckData.drivers = [ //..........................................FILL EMPTY OBJECT W/ ARRAY OF DRIVERS
    {
        firstName: "John",
        lastName: "Doe",
        company: "Company XYZ",
        vehicle: "1234"
    },

    {
        firstName: "Jane",
        lastName: "Doe",
        job: "Designer",
        vehicle: "5678"
    },

    {
        firstName: "Jake",
        lastName: "Doe",
        job: "Designer",
        vehicle: "9012"
    }
];

var getTruckDriver = function(vehicleNumber) { //........................getTruckDriver(vehicleNumber)
     var deferred = $q.defer(); //.......................................deferred is a promise

     for (var i = 0; i++; i < truckData.drivers.length) { //.............loop through all the drivers
          if (truckData.drivers[i].vehicle === vehicleNumber) { //.......is driver vehicle number equals vehicle number is true?
              deferred.resolve(truckData.drivers[i]); //.................here's the results —  no problems
          }
     }

     deferred.reject("Not found!"); //...................................errors found
     //return deferred.promise; //returns a fake promise
}

var getTrucks = function() {
     var deferred = $q.defer();
     deferred.resolve(truckData);
     return deferred.promise;
}

return {
        getTrucks: getTruckDriver,
        getTruckDriver: getTruckDriver
    }
}]);

Here’s a plunker: http://plnkr.co/edit/fR86KY?p=preview

Your getTrucks method on Plunker is returning deferred rather that deferred.promise.

Thank you!

Hey fretburner. Can you explain what’s happening with this line of code? How I use ‘truck’? What is it? I think this holds the truck array data but can’t seem to reference any of it.

$scope.model = truck

What’s happening here is that truck (an object that actually seems to represent a truck driver, rather than a truck) is being assigned to the $scope object, which makes it accessible to your view.

What is it that you’re actually trying to do?

Here’s a link to the project. Couldn’t get it working in Plunkr:

http://efeldberg.biz/assets/projects/AngularApps/Project/index.htm#/

When a user searches, live data appears from the truck array. The vehicle number shows in the URL and the length of the array shows in the console. I’m trying to get the vehicle number and company name on the page. I think this line holds the answer. I just don’t know how to work with that data.

I gather interacting with the truck object will allow me to reference properties like {{ truck.vehicle}} & {{ truck.company}}

$scope.model = truck

How would I access this in the view?

hey fretburner. I must be missing an object. I should just be able to say truck.data.company…

Hey motionographer,

Thanks for the link. It looks like you’re trying to modify the original code to make a different app? The problem is that the original code is broken… there are several problems that are stopping it from working.

In the getTruckDriver function, the for loop is broken - the 2nd and 3rd parameters are in the wrong order:

// currently
for (var i = 0; i++; i < truckData.drivers.length) { 

// should be
for (var i = 0; i < truckData.drivers.length; i++) {

In driverData.html, as the data is being assigned to $scope.model, the bindings need to reference model not truck:

<h3>Vehicle Number: {{ model.vehicle }}</h3>
<h3>Company Name: {{ model.company }}</h3>

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.