2014-07-06 21 views
7

Sto usando Angular-ui Bootstrap per la mia applicazione. Io uso la direttiva typeahead.uea typeahead angolare - impossibile leggere la proprietà 'length' di undefined

html:

<input type="text" class="pass_code_input" ng-model="SuppPrefix" Typeahead="ddl_item.Text for ddl_item in getData($viewValue)"/> 

controller

function AutoCompleteCtrl($scope,$http, AutoCompleteSrv) { 
    $scope.getData = function (prefix) { 
     AutoCompleteSrv.GetAutoComplete("Supplier", prefix).then(function (result) { 
      var results_arr = []; 
      angular.forEach(result.data, function (item) { 
       results_arr.push({ "Val": item.Val, "Text": item.Text }); 
      }); 
      return results_arr 
     }); 
    }; 
}; 

servizio:

function AutoCompleteSrv($http) { 
    var _$http = $http; 
    self = this; 
    self.GetAutoComplete = function (DataType, Prefix) { 
     var promise = _$http({ 
      method: "GET", 
      url: 'api/AutoComplete', 
      params: { 'DataType': DataType, 'Prefix': Prefix } 
     }).success(function (data, status, headers, config) { 

     }).error(function (data, status, headers, config) { 

     }); 
     return promise; 
    }; 
}; 

io ricevo i dati server, ma non riesco a visualizzarlo sullo schermo. Quando eseguo debugger in strumenti di Chrome dev, ottengo l'errore successivo:

TypeError: Cannot read property 'length' of undefined 
at http://localhost:52145/js/libs/ui-bootstrap-tpls-0.11.0.min.js:13:12650 
at m.promise.then.u (http://localhost:52145/js/angular/angular.min.js:97:280) 
at m.promise.then.u (http://localhost:52145/js/angular/angular.min.js:97:280) 
at http://localhost:52145/js/angular/angular.min.js:98:417 
at h.$eval (http://localhost:52145/js/angular/angular.min.js:108:482) 
at h.$digest (http://localhost:52145/js/angular/angular.min.js:106:62) 
at h.$apply (http://localhost:52145/js/angular/angular.min.js:109:287) 
at HTMLInputElement.l (http://localhost:52145/js/angular/angular.min.js:133:191) 
at http://localhost:52145/js/angular/angular.min.js:31:32 
at q (http://localhost:52145/js/angular/angular.min.js:7:386) 

Ho cercato per soluzione in più luoghi, come that, e anche seguito passo per passo le istruzioni nell'interfaccia utente home page di bootstrap. Cosa ho fatto di sbagliato?

+0

Non si stanno restituendo i dati nel metodo corretto, ma lo si aspetta nel controller – harishr

+0

Ho provato che bu non ha aiutato. Inoltre, quando eseguo il debug, vedo i dati nel controller (viene fornito con la promessa). I dati sono anche tornati dal controller ma poi ho ricevuto questo errore. – Lichte

+0

Puoi configurare un plunker, ti darebbe una rapida risoluzione – harishr

risposta

6

Mi sono imbattuto in questo e l'ho appena risolto. La chiave qui è che nell'esempio riportato sul sito angolare "restituiscono" i risultati $ http. Ciò lo rende confuso da guardare, ma alla fine questo è il rendimento che conta. Quindi nel tuo caso stai impostando una variabile su quel valore di ritorno in modo che il reso non venga mai restituito. Quando il tuo codice è formattato in questo modo, dovrai cambiarlo in due modi: Il primo è che l'istruzione "return" è nel posto sbagliato. Il secondo è che la dichiarazione per il valore restituito è anche nel posto sbagliato. Ecco il codice non funzionante dell'esempio:

..... 
then(function(res){ 
     var addresses = []; 
     angular.forEach(res.data.results, function(item){ 
     addresses.push(item.formatted_address); 
     }); 
     return addresses; 
    }); 

Ecco come l'ho modificato per farlo funzionare.

var addresses = [] 
.... 
then(function(res){ 
     angular.forEach(res.data.results, function(item){ 
     addresses.push(item.formatted_address); 
     }); 
    }); 
    return addresses; 

questo diventa più chiaro se non si utilizza il "poi", ma invece utilizzare il "successo" e funzioni "errore". Diventa quindi ovvio dove dovrebbe trovarsi la dichiarazione di ritorno e dove dovrebbe essere la dichiarazione del valore restituito. Scrivere il codice in questo modo e farlo funzionare è come ho capito il problema. NOTA che è necessario cancellare il valore degli indirizzi nella funzione "then" altrimenti continuerà ad aggiungere sempre più valori.

+0

Ottenendo lo stesso errore - ci sono stato per ore ora. I suggerimenti sopra non funzionano per me .. – Greg

+0

Questo mi ha salvato. Grazie. – Aravind

+0

Salvato anche me! bleh Buona regola empirica sui ritorni nelle promesse. (super nuovo alle promesse). –

0

Nei servizi, è necessario restituire i dati nella funzione di callback del metodo .success().

+0

L'ho provato ma non è stato d'aiuto. Inoltre, quando eseguo il debug, vedo i dati nel controller (viene fornito con la promessa). I dati sono anche tornati dal controller ma poi ho ricevuto questo errore. – Lichte

+0

Vedo anche una raccolta di oggetti restituiti. E ho ancora l'errore. – Stephane

4

Avevo anche questo problema.

Per me il mio controller ha chiamato il mio servizio, che stava parlando con l'API per ottenere i miei dati.

Anche se ottenere i dati funzionava (ho avuto modo di vedere questo con un console.log) nulla è stato visualizzato sulla pagina web per scegliere, e mi è stato sempre l'errore

cannot read property length of undefined 

.

Infine mi sono reso conto che dovevo restituire la mia chiamata al servizio.

//controller with code NOT working 
vm.getData = function(val, ep) { 

    myService.getData(val, ep) 
    .then(function(data){ 
    return data 
    }); 
}; 

//service 

this.getData = function(val, ep) { 
    return $http({ 
    //do http call here 
    }) 
    .then(function(data) { 
     //do what's needed with the data here 
     return data 
    }); 
}; 

la correzione che ha ottenuto questo lavoro:

//controller with code WORKING 
vm.getData = function(val, ep) { 

return myService.getData(val, ep) 
    .then(function(data){ 
    return data 
    }); 
}; 

Così ancora una volta, ho solo bisogno di tornare la mia chiamata al servizio e poi il typeahead funzionato come previsto e non più errori!

+0

Grazie, mi ha aiutato. – vanzylv

Problemi correlati