provedor desconhecido angs js

152

Estou tentando "personalizar" o exemplo do mongolab para caber na minha própria API REST. Agora estou com esse erro e não tenho certeza do que estou fazendo de errado:

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)

Este é o meu controlador:

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

e este é o módulo:

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

      return Product;
    }]);
Stefan Ernst
fonte
Este erro indica que o angular não conhece a fábrica do produto, verifique se o JS desse serviço é referência primeiro. Além disso, ao declarar os módulos, defina explicitamente as dependências, pois quando os arquivos são minimizados, esse erro também ocorre devido à manipulação do nome. Para obter mais informações, consulte este artigo :: ozkary.com/2015/11/…
ozkary

Respostas:

130

Seu código parece bom, na verdade, funciona (além das chamadas em si) quando copiado e colado em uma amostra jsFiddle: http://jsfiddle.net/VGaWD/

Difícil dizer o que está acontecendo sem ver um exemplo mais completo, mas espero que o jsFiddle acima seja útil. O que eu suspeito é que você não está inicializando seu aplicativo com o módulo 'productServices' . Daria o mesmo erro, podemos ver isso em outro jsFiddle: http://jsfiddle.net/a69nX/1/

Se você está planejando para trabalhar com AngularJS e MongoLab , sugiro usar um adaptador existente para o $ de recursos e MongoLab : https://github.com/pkozlowski-opensource/angularjs-mongolab Facilita muito da dor trabalhando com MongoLab, você pode vê-lo em ação aqui: http://jsfiddle.net/pkozlowski_opensource/DP4Rh/ Isenção de responsabilidade! Estou mantendo esse adaptador (escrito com base nos exemplos do AngularJS), portanto, obviamente estou inclinado aqui.

pkozlowski.opensource
fonte
Eu tenho o mesmo problema e isso não resolveu o meu problema. Na verdade, recebo os dados de volta ... Exceto por essa mensagem de erro, você pensaria que tudo estava funcionando bem. Porém, não estou usando o ng-app no ​​elemento body, estou inicializando assim: angular.element (document) .ready (function () {angular.bootstrap (document, ['reportServices']);});
Tom
17
Oi pessoal, isso é um pouco embaraçoso. Eu tenho exatamente o mesmo problema. Mas não consigo identificar a diferença entre os 2 jsFiddles. Qualquer dica sobre onde procurar exatamente é muito apreciada.
schacki
4
@schacki, A diferença entre os violinos pode ser encontrada na guia Informações. Um deles tem um corpo com <body ng-app="productServices">eo outro tem <body ng-app="">.
Vineet Reynolds
E onde está a guia Informações? :)
Aleks
3
Parece que o guia Informações é agora a Fiddle Optionsaba à direita
Gangstead
40

Eu recebi esse erro porque estava passando um parâmetro incorreto para a definição de fábrica. Eu tinha:

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

Funcionou quando removi $scopee alterei a definição de fábrica para:

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

Caso você precise injetar $scope, use:

myModule.factory('myService', function($rootScope, $http)...
bresleveloper
fonte
32

Eu apenas tive um problema semelhante. O erro disse o mesmo que na pergunta, tentou resolvê-lo com a resposta de pkozlowski.opensource e Ben G, que são as respostas corretas e boas.

Meu problema foi realmente diferente com o mesmo erro:

no meu código HTML, tive a inicialização assim ...

<html ng-app>

Um pouco mais abaixo, tentei fazer algo assim:

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

Eu me livrei do primeiro ... então funcionou ... obviamente você não pode inicializar o ng-app duas ou mais vezes. justo.

Eu esqueci completamente o primeiro "aplicativo ng" e fiquei totalmente frustrado. Talvez isso ajude alguém um dia ...

Preexo
fonte
2
Eu tive um problema semelhante, mas no meu caso, ter o controlador ng especificado na div era o culpado de um controlador que referencia o serviço. Parece que a Angular não sabia como resolver o serviço quando analisou a exibição.
precisa saber é o seguinte
25

Verifique se o seu principal app.jsinclui os serviços dos quais depende. Por exemplo:

/* App Module */
angular.module('myApp', ['productServices']). 
.....
BeginnerAngularJs
fonte
1
Se não me engano, nesse caso, productServicesdeve ser um módulo, por isso é irrelevante o que está dentro desse módulo (serviços ou não).
greenoldman
17

A resposta de pkozlowski está correta, mas, caso isso aconteça com outra pessoa, eu tive o mesmo erro depois de criar o mesmo módulo duas vezes por engano; a segunda definição estava substituindo o provedor da primeira:

Eu criei o módulo fazendo

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

um pouco mais abaixo no mesmo arquivo:

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

A maneira correta de fazer isso é:

angular.module('MyService'...
).factory(...).value('version','0.1');
Ben G
fonte
11

No meu caso, defini um novo provedor, digamos, xyz

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

Quando você configurou o provedor acima, você deve injetá-lo com a Providerstring anexada -> xyztorna-se xyzProvider.

Ex:

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

Se você injetar o provedor acima sem a string 'Provider', receberá um erro semelhante no OP.

manikanta
fonte
8

No final do arquivo JS para fechar a função de fábrica que eu tinha

});

ao invés de

}());

Milo P
fonte
1
Para o meu projeto normalmente usamos})();
mrOak
5

Isso me levou muito tempo para rastrear. Certifique-se de minisafe seu controlador dentro da sua diretiva.

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

  return {

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

    }]
  }
}

espero que ajude

pk1m
fonte
5

Para adicionar minha própria experiência aqui, eu estava tentando injetar um serviço em uma das minhas funções de configuração do módulo. Este parágrafo dos documentos que acabei encontrando explica por que isso não funciona:

Durante a inicialização do aplicativo, antes que o Angular saia da criação de todos os serviços, ele configura e instancia todos os provedores. Chamamos isso de fase de configuração do ciclo de vida do aplicativo. Durante esta fase, os serviços não estão acessíveis porque ainda não foram criados.

Isso significa que você pode injetar provedores nas funções module.config (...), mas não pode injetar serviços, pois é necessário aguardar até que module.run (...) ou expor um provedor que você pode injetar no módulo. config

Stewart A
fonte
4

Para mim, esse erro foi causado pela execução da versão minificada do meu aplicativo angular. Documentos angulares sugerem uma maneira de contornar isso. Aqui está a citação relevante que descreve o problema e você pode encontrar a solução sugerida nos próprios documentos aqui :

Uma observação sobre minificação Como Angular deduz as dependências do controlador dos nomes dos argumentos para a função construtora do controlador, se você minificar o código JavaScript do controlador PhoneListCtrl, todos os seus argumentos de função também serão minificados e o injetor de dependência não ser capaz de identificar serviços corretamente.

Sasha
fonte
3

Como este é o principal resultado para "fornecedor desconhecido de angularjs" no Google no momento, aqui está outra dica. Ao fazer o teste de unidade com o Jasmine, verifique se você tem esta declaração em sua beforeEach()função:

module('moduleName'); 

Caso contrário, você receberá esse mesmo erro em seus testes.

roufamatic
fonte
3

Ainda outro caso em que esse erro ocorrerá, se seu serviço estiver definido em um arquivo javascript separado, verifique se você o referenciou! Sim, eu sei, erro de novato.

Jason
fonte
2

Eu estava esquecendo de injetar o arquivo que continha meus serviços por completo. Lembre-se de fazer isso ao inicializar seu módulo de aplicativo:

angular.module('myApp', ['myApp.services', ... ]);
jorisw
fonte
2

No meu caso, usei uma função anônima como invólucro para o módulo angular, assim:

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

Depois de fechar os parênteses, esqueci de chamar a função anônima abrindo e fechando os parênteses novamente como acima.

Emanuele Bellini
fonte
Eu sei que você respondeu há 4 anos, mas me ajudou hoje, obrigado.
Legolas
1

Para mim, o problema era carregamento lento; Carreguei meu controlador e serviço com atraso, para que eles não estivessem disponíveis no carregamento da página (e na inicialização Angular). Eu fiz isso com uma tag ui-if, mas isso é irrelevante. A solução foi carregar o serviço já com o carregamento da página.

Gonfi den Tschal
fonte
1

Aqui está outro cenário possível em que você pode ver este erro:

Se você usar o Sublime Text 2 e o plug-in angular, ele gerará stubs como este

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

        }
    }
]);

observe o vazio '' como o primeiro elemento da matriz após a sequência 'utilFactory'. Se você não possui nenhuma dependência, remova-a para que fique assim:

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

        }
    }
]);
dustin.schultz
fonte
1

Como esta pergunta é o melhor resultado do Google, adicionarei outra coisa possível à lista.

Se o módulo que você está usando apresentar uma falha no wrapper de injeção de dependência, ele fornecerá o mesmo resultado. Por exemplo, os módulos copiar e colar da Internet podem contar com underscore.js e tentar injetar '_' no di wrapper. Se o sublinhado não existir nos provedores de dependência do projeto, quando o controlador tentar referenciar a fábrica do seu módulo, ele receberá 'fornecedor desconhecido' para a sua fábrica no log do console do navegador.

user1082202
fonte
1

O problema para mim foi que havia alguns novos arquivos javascript que criei que faziam referência ao serviço, mas o Chrome viu apenas a versão mais antiga. Um CTRL + F5 corrigiu para mim.

mortey
fonte
0

Eu recebi um erro de "provedor desconhecido" relacionado a zombarias angulares (ngMockE2E) ao compilar meu projeto com o Grunt. O problema era que as zombarias angulares não podem ser minificadas, então tive que removê-lo da lista de arquivos minificados.

Fausak Enferrujado
fonte
0

Depois de lidar com esse erro também, posso suportar esta lista de respostas com meu próprio caso.

Ao mesmo tempo, é simples e burra (talvez não seja burra para iniciantes como eu, mas sim para especialistas), a referência de script para angular.min.js deve ser a primeira da sua lista de scripts na página html.

Isso funciona:

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

Isso não:

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

Aviso sobre o angular.min.js.

Espero que ajude alguém !! :)

Joe Lewis
fonte
0

Meu problema foi com Yeoman, usando (maiúsculo):

yo angular:factory Test

Arquivos criados (sem capitalização):

app/scripts/services/test.js

mas o arquivo index.html incluía (capitalizado):

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

Espero que isso ajude alguém.

Corey Rothwell
fonte
0

Mais uma possibilidade.

Eu tive unknown Provider <- <- nameOfMyService. O erro foi causado pela seguinte sintaxe:

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

Angular estava procurando a ''dependência.

Hugo Wood
fonte
Erro: [$ injector: despr] Provedor desconhecido: LoginFactoryProvider <- LoginFactory eu tenho esse aqui, então como posso corrigir esse aqui?
ninjaXnado
0

Meu cenário pode ser um pouco obscuro, mas pode causar o mesmo erro e alguém pode experimentar, portanto:

Ao usar o serviço $ controller para instanciar um novo controlador (que estava esperando '$ scope' como seu primeiro argumento injetado), eu estava passando o novo escopo local do controlador para o segundo parâmetro da função $ controller (). Isso levou o Angular a tentar invocar um serviço $ scope que não existe ( embora, por algum tempo, eu realmente tenha pensado em como excluir o serviço '$ scope' do cache do Angular ). A solução é agrupar o escopo local em um objeto locals:

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

// Good:
$controller('myController, {$scope: newScope});
Zac Seth
fonte
0

Nenhuma das respostas acima funcionou para mim, talvez eu estivesse me enganando completamente, mas como iniciante é isso que fazemos.

Eu estava inicializando o controlador em um divpara ter uma lista:

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

E então usando $routeProviderpara mapear uma URL para o mesmo controlador. Assim que eu removi ng-inito controlador funcionou com a rota.

jfs.csantos
fonte
0

Eu tive o mesmo problema. Corrigi isso usando em $('body').attr("ng-app", 'MyApp')vez de <body ng-app="MyApp">boostrap.

Porque eu fiz

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

para requisitos de arquitetura.

Jokerm
fonte
0

No meu aplicativo Ruby on Rails, eu fiz o seguinte:

rake assets:precompile

Isso foi feito no ambiente de 'desenvolvimento', que reduziu o Angular.js e o incluiu no /public/assets/application.jsarquivo.

A remoção dos /public/assets/*arquivos resolveu o problema para mim.

Nigel Sheridan-Smith
fonte
0

Enfrentei um problema semelhante hoje e os problemas eram realmente muito pequenos

 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);
            }
        }
    }
}
});

Se você observar o bloco acima, na primeira linha, observará que eu injetei $ scope por engano, o que está incorreto. Eu removi essa dependência indesejada para resolver o problema.

 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
fonte
0

Eu tive esse erro depois de criar uma nova fábrica e usá-lo em um componente, mas não verifiquei as especificações desses componentes

portanto, se a falha nos seus arquivos de teste (especificações)

você precisa adicionar beforeEach(module('YouNewServiceModule'));

Basheer AL-MOMANI
fonte
-1

Outra 'pegadinha': eu estava recebendo esse erro ao injetar $ timeout, e levou alguns minutos para perceber que eu tinha espaço em branco nos valores da matriz. Isso não vai funcionar:

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

Publicar apenas no caso de alguém ter um erro bobo como este.

Lukus
fonte
-2

Meu caso foi de digitação desonesta

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

função tem um 'c'!

desembarcou
fonte