5

Quando si cerca di interrogare un metodo personalizzato copies su una risorsa AngularJS ottengo il seguente errore in angular.js:10033: (. Il metodo copy funziona bene)TypeError: undefined non è una funzione in angolare Resource

TypeError: undefined is not a function 
at https://code.angularjs.org/1.3.0-beta.8/angular-resource.min.js:9:347 
at Array.forEach (native) 
at q (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:7:280) 
at q.then.p.$resolved (https://code.angularjs.org/1.3.0-beta.8/angular-resource.min.js:9:329) 
at J (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:101:5) 
at J (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:101:5) 
at https://code.angularjs.org/1.3.0-beta.8/angular.min.js:102:173 
at g.$eval (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:113:138) 
at g.$digest (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:110:215) 
at g.$apply (https://code.angularjs.org/1.3.0-beta.8/angular.min.js:113:468) 

angolare js 10.016-10.035:

function consoleLog(type) { 
    var console = $window.console || {}, 
     logFn = console[type] || console.log || noop, 
     hasApply = false; 

    // Note: reading logFn.apply throws an error in IE11 in IE8 document mode. 
    // The reason behind this is that console.log has type "object" in IE8... 
    try { 
    hasApply = !!logFn.apply; 
    } catch (e) {} 

    if (hasApply) { 
    return function() { 
     var args = []; 
     forEach(arguments, function(arg) { 
     args.push(formatError(arg)); 
     }); 
     return logFn.apply(console, args); // This is line 10033 where the error gets thrown. 
    }; 
    } 

risorsa semplificata:

angular.module('vgm.content-pages') 
.factory('ContentPage', function($resource, $http) { 

    return $resource('/api/content-page/:id', { id:'@page.id' }, { 
    copy: { 
     method: 'POST', 
     url: '/api/content-page/copy/:id' 
    }, 
    copies: { 
     method: 'GET', 
     isArray: true, 
     url: '/api/content-page/copies/:id' 
    } 
    }); 

}); 

direttiva semplificato dove sto ottenendo l'errore:

angular.module('vgm.genericForms') 
.directive('vgmFormCopyPicker', function() { 

    return { 
    restrict: 'E', 
    replace: true, 
    templateUrl: '/static/common/generic-forms/widgets/view-copy-picker.html', 
    scope: { 
     resource: '=', 
    }, 
    controller: function($scope, $element) { 

     $scope.pages = []; 

     $scope.loadCopies = function() { 

     $scope.resource.$copies() 
      .then(function(response) { 
      $scope.pages = response.data; 
      }); 

     }; 

    } 
    }; 

}); 

Appena ho eseguito il metodo loadCopies, eseguendo la linea $scope.resource.$copies() getta l'errore precedente.

In Chrome Inspector vedo che la chiamata alla mia API viene effettivamente eseguita. Ma risolvere la promessa sembra gettare qualche errore ...

Come posso risolvere questo errore?

EDIT:

$scope.resource = ContentPage.get({id: $stateParams.id}).$promise 
$scope.resource.$save() // Works 
$scope.resource.$update() // Works 
$scope.resource.$copy() // Works 
$scope.resource.$copies() // Does not work! 

Resource angolare sta cercando di sovrascrivere la mia risorsa iniziale con un array di oggetti. Ma l'istanza di Risorsa non ha un metodo push ovviamente.

risposta

8

ho trovato la risposta:

Una risorsa dovrebbe rappresentare l'oggetto di dati abbinati per il resto della sua vita. Se vuoi recuperare nuovi dati, dovresti farlo con un nuovo oggetto.

$scope.copies = ContentPage.copies() 
+0

Grazie Guido. Ho avuto lo stesso problema. Penso che i documenti siano un po 'confusi. Se sto capendo correttamente, non puoi chiamare un metodo di istanza che ha isArray: true su un'istanza/single/resource perché la singola istanza non è una matrice. –

+1

Questo è corretto. E ha senso se ci pensate: prima la proprietà rappresenta un elenco di elementi, e all'improvviso rappresenta un singolo oggetto, che non è coerente. –

6

La risposta di Guido è corretta ma non l'ho ricevuta al primo tentativo.

Se si aggiunge un metodo personalizzato a Angular $resource e si utilizza isArray: true e si prevede di ottenere una matrice di qualcosa dal proprio WebService, è probabile che si desideri memorizzare la risposta in una matrice.

Pertanto non si dovrebbe utilizzare il metodo di istanza in questo modo:

var ap = new Ansprechpartner(); 
$scope.nameDuplicates = ap.$searchByName(...); 

Ma utilizzare la risorsa direttamente:

$scope.nameDuplicates = Ansprechpartner.searchByName(...) 

Utilizzando seguente risorsa angolare:

mod.factory('Ansprechpartner', ['$resource', 
    function ($resource) { 
     return $resource('/api/Ansprechpartner/:id', 
      { id: '@ID' }, 
      { 
       "update": { method: "PUT" }, 
       "searchByName": { method: "GET", url: "/api/Ansprechpartner/searchByName/:name", isArray: true } 
      } 
     ); 
    } 
]); 
+0

Questo commento ha concluso mezza giornata di dolore per me, thx. – bertrand

-1

Sono usando Mean.js e questo afflitto per alcune ore. C'è un built-in $update ma non funzionava quando ho provato ad applicarlo a un oggetto restituito da un $resource. Per farlo funzionare ho dovuto cambiare il modo in cui stavo chiamando la risorsa per aggiornarlo.

Ad esempio, con un modulo Student, lo stavo restituendo con un $resource in $scope.student. Quando ho provato ad aggiornare student.$update restituivo questo errore.Modificando la chiamata per essere Students.update() ha risolto il problema.

$scope.update = function() { 
 
    var student = $scope.student; 
 
    var result = Students.update(student); 
 

 
    if(result){ 
 
     $scope.message = 'Success'; 
 
    } else { 
 
     $scope.error = 
 
     'Sorry, something went wrong.'; 
 
    } 
 
};

Problemi correlati