angular js nieznany dostawca

152

Próbuję „dostosować” przykład mongolabu, aby pasował do mojego własnego interfejsu API REST. Teraz napotykam ten błąd i nie jestem pewien, co robię źle:

Error: Unknown provider: ProductProvider <- Product
    at Error (unknown source)
    at http://localhost:3000/js/vendor/angular.min.js:28:395
    at Object.c [as get] (http://localhost:3000/js/vendor/angular.min.js:26:180)
    at http://localhost:3000/js/vendor/angular.min.js:28:476
    at c (http://localhost:3000/js/vendor/angular.min.js:26:180)
    at d (http://localhost:3000/js/vendor/angular.min.js:26:314)

To jest mój kontroler:

function ProductListCtrl($scope, Product) {
  $scope.products = Product.query();
}

a to jest moduł:

angular.module('productServices', ['ngResource']).
    factory('Product', ['$resource', function($resource){
      var Product = $resource('/api/products/:id', {  }, {
        update: { method: 'PUT' }
      });

      return Product;
    }]);
Stefan Ernst
źródło
Ten błąd oznacza, że ​​firma Angular nie wie o fabryce produktu, upewnij się, że JS dla tej usługi jest pierwszym punktem odniesienia. Również podczas deklarowania modułów upewnij się, że jawnie zdefiniowałeś zależności, ponieważ gdy pliki są zminimalizowane, ten błąd również wystąpiłby z powodu zniekształcenia nazwy. Aby uzyskać więcej informacji, spójrz na ten artykuł :: ozkary.com/2015/11/…
ozkary

Odpowiedzi:

130

Twój kod wygląda dobrze, w rzeczywistości działa (oprócz samych wywołań) po skopiowaniu i wklejeniu do przykładowego pliku jsFiddle: http://jsfiddle.net/VGaWD/

Trudno powiedzieć, co się dzieje, nie widząc pełniejszego przykładu, ale mam nadzieję, że powyższy jsFiddle będzie pomocny. Podejrzewam, że nie inicjujesz aplikacji za pomocą modułu „productServices” . Dałby ten sam błąd, widzimy to w innym jsFiddle: http://jsfiddle.net/a69nX/1/

Jeśli planujesz pracować z AngularJS i MongoLab , sugerowałbym użycie istniejącego adaptera dla zasobu $ i MongoLab : https://github.com/pkozlowski-opensource/angularjs-mongolab Zmniejsza wiele bólu podczas pracy z MongoLab, można zobaczyć to w akcji tutaj: http://jsfiddle.net/pkozlowski_opensource/DP4Rh/ Disclaimer! Utrzymuję ten adapter (napisany na podstawie przykładów AngularJS), więc jestem tutaj oczywiście stronniczy.

pkozlowski.opensource
źródło
Mam ten sam problem i to nie rozwiązało mojego problemu. Właściwie odzyskuję dane ... Oprócz tego komunikatu o błędzie można by pomyśleć, że wszystko działa dobrze. Nie używam jednak ng-app w elemencie body, ładuję w ten sposób: angular.element (dokument) .ready (function () {angular.bootstrap (dokument, ['reportServices']);});
Tom
17
Cześć, to trochę zawstydzające. Mam dokładnie ten sam problem. Ale nie mogę dostrzec różnicy między 2 jsFiddles. Każda wskazówka, gdzie dokładnie szukać, jest bardzo cenna.
schacki
4
@schacki, Różnicę w skrzypcach można znaleźć w zakładce info. Jeden z nich ma ciało, <body ng-app="productServices">a drugi ma <body ng-app="">.
Vineet Reynolds
A gdzie jest zakładka informacyjna? :)
Aleks
3
Wygląda na to, że zakładka informacyjna jest teraz Fiddle Optionszakładką po prawej
Gangstead,
40

Otrzymałem ten błąd, ponieważ przekazywałem nieprawidłowy parametr do definicji fabrycznej. Miałem:

myModule.factory('myService', function($scope, $http)...

Zadziałało, gdy usunąłem $scopei zmieniłem definicję fabryki na:

myModule.factory('myService', function( $http)...

W przypadku konieczności wstrzyknięcia $scopeużyj:

myModule.factory('myService', function($rootScope, $http)...
bresleveloper
źródło
32

Właśnie miałem podobny problem. Błąd powiedział to samo w pytaniu, próbowałem go rozwiązać za pomocą odpowiedzi pkozlowski.opensource i Ben G, które są poprawne i dobre.

Mój problem był rzeczywiście inny z tym samym błędem:

w moim kodzie HTML miałem taką inicjalizację ...

<html ng-app>

Nieco dalej próbowałem zrobić coś takiego:

<div id="cartView" ng-app="myApp" ng-controller="CartCtrl">

Pozbyłem się pierwszego ... wtedy zadziałało ... oczywiście nie możesz inicjalizować ng-app dwa lub więcej razy. Słusznie.

Całkowicie zapomniałem o pierwszej "ng-aplikacji" i byłem totalnie sfrustrowany. Może to kiedyś komuś pomoże ...

Preexo
źródło
2
Miałem podobny problem, ale w moim przypadku posiadanie ng-kontrolera określonego w div było winowajcą kontrolera, który odwołuje się do usługi. Wygląda na to, że Angular nie wiedział, jak rozwiązać usługę, gdy przeanalizował widok.
Hector Correa
25

Upewnij się, że twój main app.jszawiera usługi, od których zależy. Na przykład:

/* App Module */
angular.module('myApp', ['productServices']). 
.....
BeginnerAngularJs
źródło
1
Jeśli się nie mylę to w takim przypadku productServicespowinien to być moduł, więc nie ma znaczenia, co jest w środku takiego modułu (usługi czy nie).
greenoldman
17

odpowiedź pkozłowskiego jest poprawna, ale na wypadek, gdyby zdarzyło się to komuś innemu, miałem ten sam błąd po dwukrotnym utworzeniu tego samego modułu przez pomyłkę; druga definicja unieważnia dostawcę pierwszej:

Stworzyłem moduł wykonując

angular.module('MyService'...
).factory(...);

potem nieco dalej w tym samym pliku:

angular.module('MyService'...
).value('version','0.1');

Prawidłowy sposób to:

angular.module('MyService'...
).factory(...).value('version','0.1');
Ben G.
źródło
11

W moim przypadku zdefiniowałem nowego dostawcę, powiedzmy xyz

angular.module('test')
.provider('xyz', function () {
    ....
});

Kiedy miałeś skonfigurować powyższego dostawcę, musisz wstrzyknąć go z Providerdołączonym ciągiem -> xyzstaje się xyzProvider.

Dawny:

angular.module('App', ['test'])
.config(function (xyzProvider) {
     // do something with xyzProvider....
});

Jeśli wstrzykniesz powyższego dostawcę bez ciągu „Provider”, otrzymasz podobny błąd w OP.

manikanta
źródło
8

Na końcu pliku JS, aby zamknąć funkcję fabryczną, którą miałem

});

zamiast

}());

Milo P.
źródło
1
W moim projekcie zwykle używamy})();
mrOak
5

Wytropienie tego zajęło mi zbyt dużo czasu. Upewnij się, że minimalizujesz bezpieczeństwo kontrolera w ramach dyrektywy.

.directive('my_directive', ['injected_item', function (injected_item){

  return {

    controller: ['DO_IT_HERE_TOO', function(DO_IT_HERE_TOO){

    }]
  }
}

Mam nadzieję, że to pomoże

pk1m
źródło
5

Aby dodać tutaj własne doświadczenie, próbowałem wstrzyknąć usługę do jednej z moich funkcji konfiguracyjnych modułu. Ten akapit z dokumentów, które w końcu znalazłem, wyjaśnia, dlaczego to nie działa:

Podczas ładowania aplikacji, zanim Angular rozpocznie tworzenie wszystkich usług, konfiguruje i tworzy instancje wszystkich dostawców. Nazywamy to fazą konfiguracji cyklu życia aplikacji. Na tym etapie usługi nie są dostępne, ponieważ nie zostały jeszcze utworzone.

Oznacza to, że możesz wstrzyknąć dostawców do funkcji module.config (...), ale nie możesz wstrzyknąć usług, w tym celu musisz poczekać, aż module.run (...), lub ujawnić dostawcę, którego możesz wstrzyknąć do modułu. config

Stewart A.
źródło
4

U mnie ten błąd był spowodowany uruchomieniem zminimalizowanej wersji mojej aplikacji kątowej. Doktorzy Angular sugerują sposób obejścia tego problemu. Oto odpowiedni cytat opisujący problem, a sugerowane rozwiązanie można znaleźć w samych dokumentach tutaj :

Uwaga na temat minifikacji Ponieważ Angular wnioskuje zależności kontrolera z nazw argumentów do funkcji konstruktora kontrolera, gdybyś zminimalizował kod JavaScript dla kontrolera PhoneListCtrl, wszystkie jego argumenty funkcji również zostałyby zminimalizowane, a iniektor zależności nie. być w stanie poprawnie zidentyfikować usługi.

Sasha
źródło
3

Ponieważ jest to obecnie najwyższy wynik dla „nieznanego dostawcy angularjs” w Google, oto kolejny problem. Wykonując testy jednostkowe z Jasmine, upewnij się, że masz w beforeEach()funkcji następującą instrukcję :

module('moduleName'); 

W przeciwnym razie w testach wystąpi ten sam błąd.

roufamatic
źródło
3

Jeszcze inny przypadek, w którym wystąpi ten błąd, jeśli Twoja usługa jest zdefiniowana w oddzielnym pliku javascript, upewnij się, że odwołujesz się do niego! Tak, wiem, błąd debiutanta.

Jason
źródło
2

Zapomniałem wstrzyknąć plik, który całkowicie zawierał moje usługi. Pamiętaj, aby zrobić to podczas inicjowania modułu aplikacji:

angular.module('myApp', ['myApp.services', ... ]);
jorisw
źródło
2

W moim przypadku użyłem anonimowej funkcji jako otoki dla modułu kątowego, na przykład:

(function () {
var app = angular.module('myModule', []);
...
})();

Po zamknięciu nawiasów zapomniałem wywołać funkcję anonimową, otwierając i ponownie zamykając nawiasy, jak powyżej.

Emanuele Bellini
źródło
Wiem, że odpowiedziałeś na to 4 lata temu, ale pomogło mi to dzisiaj, dzięki.
Legolas
1

Dla mnie problemem było leniwe ładowanie; Późno załadowałem kontroler i usługę, więc nie były one dostępne podczas ładowania strony (i inicjalizacji Angular). Zrobiłem to z tagiem ui-if, ale to nie ma znaczenia. Rozwiązaniem było załadowanie usługi już z załadowaną stroną.

Gonfi den Tschal
źródło
1

Oto kolejny możliwy scenariusz, w którym można zobaczyć ten błąd:

Jeśli używasz Sublime Text 2 i wtyczki kątowej, wygeneruje ona takie kody pośredniczące

angular.module('utils', [])
.factory('utilFactory', [''
    function() {
        return {

        }
    }
]);

zwróć uwagę na pusty „” jako pierwszy element tablicy po ciągu „utilFactory”. Jeśli nie masz żadnych zależności, usuń to, aby wyglądało tak:

angular.module('utils', [])
.factory('utilFactory', [
    function() {
        return {

        }
    }
]);
dustin.schultz
źródło
1

Ponieważ to pytanie jest najlepszym wynikiem w Google, dodam do listy kolejną możliwą rzecz.

Jeśli moduł, którego używasz, ma błąd w otoce iniekcji zależności, zapewni ten sam wynik. Na przykład moduły kopiowania i wklejania z Internetu mogą polegać na underscore.js i próbować wstrzyknąć znak „_” w opakowaniu di. Jeśli podkreślenie nie istnieje w dostawcach zależności projektu, gdy kontroler spróbuje odwołać się do fabryki modułu, otrzyma „nieznanego dostawcę” dla fabryki w dzienniku konsoli przeglądarki.

user1082202
źródło
1

Problem polegał na tym, że utworzyłem kilka nowych plików javascript, które odwoływały się do usługi, ale Chrome widział tylko starszą wersję. CTRL + F5 naprawił to za mnie.

Mortey
źródło
0

Podczas kompilowania projektu za pomocą Grunt wystąpił błąd „nieznanego dostawcy” związany z makietami kątowymi (ngMockE2E). Problem polegał na tym, że makiety kątowe nie mogły zostać zminimalizowane, więc musiałem usunąć je z listy zminimalizowanych plików.

Zardzewiały Fausak
źródło
0

Po rozwiązaniu tego błędu również mogę wesprzeć tę listę odpowiedzi w mojej własnej sprawie.

Jest to jednocześnie proste i głupie (może nie głupie dla początkujących jak ja, ale tak dla ekspertów), odniesienie do skryptu angular.min.js musi być pierwszym na liście skryptów na stronie html.

To działa:

<script src="Scripts/angular.min.js"></script>
<script src="MyScripts/MyCartController.js"></script>
<script src="MyScripts/MyShoppingModule.js"></script>

To nie:

<script src="MyScripts/MyCartController.js"></script>
<script src="MyScripts/MyShoppingModule.js"></script>
<script src="Scripts/angular.min.js"></script>

Uwaga dotycząca pliku angular.min.js.

Mam nadzieję, że to pomoże każdemu! :)

Joe Lewis
źródło
0

Mój problem dotyczył Yeoman, używając (pisane wielkimi literami):

yo angular:factory Test

Wykonane pliki (bez wielkich liter):

app/scripts/services/test.js

ale dołączony plik index.html (pisany wielkimi literami):

<script src="scripts/services/Test.js"></script>

Mam nadzieję, że to komuś pomoże.

Corey Rothwell
źródło
0

Jeszcze inna możliwość.

Miałem unknown Provider <- <- nameOfMyService. Błąd został spowodowany następującą składnią:

module.factory(['', function() { ... }]);

Angular szukał ''zależności.

Hugo Wood
źródło
Błąd: [$ injector: unpr] Nieznany dostawca: LoginFactoryProvider <- LoginFactory mam to, więc jak mogę to naprawić
ninjaXnado
0

Mój scenariusz może być trochę niejasny, ale może powodować ten sam błąd i ktoś może go doświadczyć, więc:

Podczas korzystania z usługi $ controller do tworzenia instancji nowego kontrolera (który oczekiwał „$ scope” jako pierwszego wstrzykniętego argumentu) przekazywałem lokalny zakres nowego kontrolera do drugiego parametru funkcji $ controller (). To doprowadziło do tego, że Angular próbował wywołać usługę $ scope, która nie istnieje ( chociaż przez chwilę myślałem, że w jakiś sposób usunę usługę '$ scope' z pamięci podręcznej Angulara ). Rozwiązaniem jest zawinięcie zakresu lokalnego w obiekt lokalny:

// Bad:
$controller('myController', newScope);

// Good:
$controller('myController, {$scope: newScope});
Zac Seth
źródło
0

Żadna z powyższych odpowiedzi nie zadziałała dla mnie, może robiłem zupełnie źle, ale jako początkujący tak właśnie robimy.

Inicjalizowałem kontroler divw celu uzyskania listy:

 <div ng-controller="CategoryController" ng-init="initialize()">

A następnie użycie $routeProviderdo mapowania adresu URL na ten sam kontroler. Jak tylko zdjąłem ng-initkontroler działał z trasą.

jfs.csantos
źródło
0

Miałem ten sam problem. Naprawiłem to używając $('body').attr("ng-app", 'MyApp')zamiast<body ng-app="MyApp"> Boostrap.

Ponieważ to zrobiłem

angular.element(document).ready(function () {        
    angular.bootstrap(document, [App.Config.Settings.AppName]);
})

do wymagań architektonicznych.

Jokerm
źródło
0

W mojej aplikacji Ruby on Rails wykonałem następujące czynności:

rake assets:precompile

Zrobiono to w środowisku „programistycznym”, które zminimalizowało Angular.js i włączyło go do /public/assets/application.jspliku.

Usunięcie /public/assets/*plików rozwiązało problem za mnie.

Nigel Sheridan-Smith
źródło
0

Zmierzyłem się dzisiaj z podobnym problemem i problemy były naprawdę bardzo małe

 app.directive('removeFriend', function($scope) {
return {
    restrict: 'E',
    templateUrl: 'removeFriend.html',
    controller: function($scope) {
        $scope.removing = false;
        $scope.startRemove = function() {
            $scope.removing = true;
        }
        $scope.cancelRemove = function() {
            $scope.removing = false;
        }
        $scope.removeFriend = function(friend) {
            var idx = $scope.user.friends.indexOf(friend)
            if (idx > -1) {
                $scope.user.friends.splice(idx, 1);
            }
        }
    }
}
});

Jeśli zauważysz powyższy blok, w pierwszym wierszu zauważysz, że przez pomyłkę wstrzyknąłem $ scope, co jest niepoprawne. Usunąłem tę niechcianą zależność, aby rozwiązać problem.

 app.directive('removeFriend', function() {
return {
    restrict: 'E',
    templateUrl: 'removeFriend.html',
    controller: function($scope) {
        $scope.removing = false;
        $scope.startRemove = function() {
            $scope.removing = true;
        }
        $scope.cancelRemove = function() {
            $scope.removing = false;
        }
        $scope.removeFriend = function(friend) {
            var idx = $scope.user.friends.indexOf(friend)
            if (idx > -1) {
                $scope.user.friends.splice(idx, 1);
            }
        }
    }
}
});
Rakesh Burbure
źródło
0

Miałem ten błąd po utworzeniu nowej fabryki i zastosowaniu jej w komponencie, ale nie sprawdziłem specyfikacji tych komponentów

więc jeśli błąd w plikach testowych (specyfikacji)

musisz dodać beforeEach(module('YouNewServiceModule'));

Basheer AL-MOMANI
źródło
-1

Kolejna „łapanka”: otrzymywałem ten błąd podczas wstrzykiwania $ timeout i zajęło mi kilka minut, zanim zdałem sobie sprawę, że w wartościach tablicy mam białe znaki. To nie zadziała:

angular.module('myapp',[].
  controller('myCtrl', ['$scope', '$timeout ', 
    function ($scope, $timeout){
      //controller logic
    }
  ]);

Publikowanie na wypadek, gdyby ktoś inny miał taki głupi błąd.

Lukus
źródło
-2

Mój przypadek był podejrzany

myApp.factory('Notify',funtion(){

funkcja ma „c”!

wylądował
źródło