user1056607
user1056607

Reputation: 55

AngularJS : undefined is not a function from factory

I have multiple functions inside of my factory and I cannot call my saveCharacter function from a button click using ng-click. The getCharacters function works just fine. Sorry in advance for the repost, I have gone over many different examples and cannot solve my particular issue with those. I can see my functions when I log the xmlService, but i'm not sure why it won't call to it. I was trying to return a post to a PHP file in saveCharacter, but changed to a string return to try to test to see what my issue was.

Thanks again for any help.

(function(){

var app = angular.module('arena', []);

app.factory('xmlService', function($http){

    var factory = {};

    factory.getCharacter = function getCharacter(){         
        return $http.get('xml/characterTemplate.xml');
    };
    factory.saveCharacter = function saveCharacter(){
        return "hello";
        //return $http.post('php/crud.php');
    };

    return factory;

});

app.controller('FighterController', ['$scope','xmlService', function($scope, xmlService){
    this.fighterList = fighterList;


    $scope.saveFighter = function saveFighter(){
        console.log(xmlService);
        xmlService.saveCharacter.success(function(data){
            console.log(data);
        });
    }

    function loadFighters(){


        xmlService.getCharacter().success(function(data){
            var x2js = new X2JS(); 
            var charactersList  = x2js.xml_str2json(data);

            for(var i = 0; i < charactersList.characters.character.length; i++)
            {
                var currentFighter = charactersList.characters.character[i];
                fighterList.push(currentFighter);

            }                
            $scope.FighterController = charactersList;
        });
    }
    loadFighters();
}]);



var fighterList = [
];

})();

Other questions I had while writing my first Angular app, what is the point of the code:

$scope.FighterController = charactersList;

does that allow me to access the returned data on the view side? do I have to reset the scope in my saveFighter function to cause my button to work?

Am I setting the dependencies correctly for my app.controller, and is that dependency injection?

Thank you all, and any comments on how my code is setup are greatly appreciated!

Upvotes: 0

Views: 1916

Answers (3)

JLRishe
JLRishe

Reputation: 101652

You haven't really explained what you did to fix this issue, so I'll explain it.

Here, you are trying to call xmlService.saveCharacter.success():

xmlService.saveCharacter.success(function(data){
        console.log(data);
});

But xmlService.saveCharacter is a function. It has no success property; success is undefined. So this gives the error you were seeing.

You need to call xmlService.saveCharacter():

xmlService.saveCharacter().success(function(data){
        console.log(data);
});

But this is still a problem because the saveCharacter() function returns the string "hello". This string doesn't have a success property. Yet again success is undefined, so now that causes the same error.

To fix that error, you just need to remove the return "hello"; and uncomment the code you had commented out:

factory.saveCharacter = function saveCharacter(){
    return $http.post('php/crud.php');
};

Fixing those two problems should remedy your issue.

Upvotes: 3

user1056607
user1056607

Reputation: 55

I adjusted my factory to this structure and now I can call my functions.

app.factory('xmlService', function($http){

    var factory = {
        getCharacter: function(){
            return $http.get('xml/characterTemplate.xml');
        },
        saveCharacter:function(){
            console.log('hello?');
            return $http.post('php/crud.php');
        }
    };
    return factory;

}); 

in my controller

$scope.saveFighter = function(){
        console.log(xmlService);
        xmlService.saveCharacter().success(function(data){
            console.log(data);
        });

    }

    function loadFighters(){
        xmlService.getCharacter().success(function(data){
            var x2js = new X2JS(); 
            var charactersList  = x2js.xml_str2json(data);

            for(var i = 0; i < charactersList.characters.character.length; i++)
            {
                var currentFighter = charactersList.characters.character[i];
                fighterList.push(currentFighter);

            }                
            $scope.FighterController = charactersList;
        });
    }
    loadFighters();

Upvotes: 0

Zaheer Ahmed
Zaheer Ahmed

Reputation: 28528

You are missing invoking a function with () change code to:

$scope.saveFighter = function saveFighter(){
    console.log(xmlService);

    xmlService.saveCharacter().success(function(data){
    // ----------------------^
        console.log(data);
    });
 }

$scope.FighterController = charactersList;is assigning data of characterList to scope variable and scope variable are accessible in html scope is like a bridge between controller and views.

I recommend you to start reading angularjs

Upvotes: 0

Related Questions