trouble using JavaScript pseudo-classes in an Angular Service defined using a factory method

54 views
Skip to first unread message

Doug Snyder

unread,
Mar 19, 2014, 6:35:41 PM3/19/14
to ang...@googlegroups.com
I'm new both to AngularJS and JavaScript and probably most people learning Angular have more JavaScript experience than I do.
I'm trying to use a simple JavaScript pattern for creating pseudo classes using JavaScript funcitons that I've learned with a pattern for Angular services from the Angular docs.
Sadly they don't go together and I am left baffled since I don't understand enough about the internals of JavaScript that seem to govern the hackish seeming ( to me ) nature of either of these patterns to trouble shoot it myself. But I'm gathering that there must be a fairly easy way to have pseudo classes in Angular that most people probably don't see the need to explain.

So my pseudo class looks like this:

function Node( data) {

this.node_data  = data;

 this.status = 'NEW";
 

this.doSomething = function (param) {

    if (param == 'SOMETHING')

    return "RESULT1";

    else

    return "RESULT1";

  };


 this.getCSSClass = function() {
 
if (this.status == "NEW")
 return 'new';
else return 'old'; 
 };
}; 

so can pass parameters to a pseudo constructer and my class fields and methods can be accessed under this
this works fine for me when I use it in a controller. In angular there are multiple patterns to implement a controller, but I am using this:

myApp.controller('NodeCtrl', ['$scope','$rootScope' ,function($scope, $rootScope

{

$scope.some_var = null;


          $scope.someScopeMethod = function() {
 console.log('scope did something');
 };
 

function Nodedata) {

this.node_data  = data;

 this.status = 'NEW";
 

this.doSomething function (param) {

    if (param == 'SOMETHING')

    return "RESULT1";

    else

    return "RESULT1";

  };


 this.getCSSClass = function() {
 
if (this.status == "NEW")
 return 'new';
else return 'old'; 
 };
}; 

$scope.someOtherScopeMethod = function() { 
 
console.log('scope did something else');
};
}]); 
 

So $scope holds the scope for my Angular related stuff and I have class whose scope is referenced by this within the class
This works fine, its when I want to repeat this class pattern with in a service instead of a controller that I get lost:
There are various patterns for a service but I am using this factory method:

myApp.factory('nodeService', function($rootScope) { 
var my_service_var1 = null;
          var my_node_list = [];
 return {
aServiceMethod: function(param) {
 console.log('doing something in my service');
},
Node:function(data) { 

this.node_data  = data;

 this.status = 'NEW";
 

this.doSomething function (param) {

    if (param == 'SOMETHING')

    return "RESULT1";

    else

    return "RESULT1";

  };


 this.getCSSClass = function() {
 
if (this.status == "NEW")
 return 'new';
else return 'old'; 
 };
},  
 
anotherServiceMethod: function(param) {
 console.log('doing something else in my service');
}
 
}; 
 );
 
So here the factory function is returning the service methods as a JSON object, which is not something I'm farmiliar with in JavaScript.
I'm just copying this pattern from ANgularJS's docs and don't understand exactly why its causing trouble.
What happens is my class scope referenced by this within the Node class references both the class variables I expect it to but it also
references the service variables and methods, which I do not want. I want the Node class to have its own seperate scope from everything else.
So my question is how to do this using the factory method for a service?
It may something as simple as defining the Node pseudo class outside of the factory method definition for my service and somehow referencing or injecting the
Node pseudo class into the service so I can use it there, but I haven't been able to find if this is possible as it seems to be a hard question to frame given my inexperience
in a way that a search engine understands.
I'm starting to understand Angular's architecture and it seems quite well thought out,
but less well thought out is how to explain it to people like me where the architecture seems to make the simple creation of a class into a problem I can't solve myself.
Anyone that wants to add some advice or philosophy about using pseudo classes like I am trying to is welcome to educate a willing noob.
I am basically accessing REST endpoints to initialize different items stored in pseaudo classes like my node class
and having some functionality built into the class as well as passing say a list of these objects to ng-repeat for display.
I guess the alternative to this approach is just storing the items as JSON objects with no class wrapper and having the functionality in stand alone methods that
take the item as a JSON object as a parameter.
Using classes seems more powerful but maybe this is just a shift I have to make when using Angular?

Doug 

Luke Kende

unread,
Mar 20, 2014, 1:48:05 AM3/20/14
to ang...@googlegroups.com
Yep, javascript has a learning curve when coming from other programming languages.  I'm not claiming to be an expert but I understand a thing or two, so maybe can offer some direction.  It's hard to follow what you are after completely, but I'll try.

First, you are reading and trying things from the tutorial, so good job.  You are headed down the right path.  Second, 'pseudo class'  is a reference to css classes, not javascript.  It looks like you are actually asking about using a javascript as OO and using a function to define the class.  Glad you recognize the difference between a json object and a class defined object.

Now, your factory is returning the json defined from the object notation using curly braces.  Since a factory only returns what the function returns, when you inject it into the controller, what you see is what you get.

return {
  somevariable: 'string value',
  somefunction: function(){ return 'Im a function!' }
}

If this is what your nodeService returned then these 'named' references are available as dot notation or array notation from nodeService:
console.log(nodeService.somevariable); //string value
console.log(nodeService['somevariable']); //string value
var result = nodeService.somefunction();
console.log(result); //im a function


As you have it, if what you are really after is a new Node instance from the factory, then you can just call it in the controller:

var myNode = new nodeService.Node({ message: 'its a trap!', isNode: true });
console.log(myNode.node_data.message); //its a trap!

It doesn't matter that the nodeService also exposes other properties and functions.

If you want only one instance from the factory, you could define the function above your return statement in the factory and new it in the return statement:

..other service stuff...
function Node(data ){ ...your function stuff...  }

return new Node({ message: 'its not a tumor', isNode: true });


then in controller you would have:

console.log(nodeService.node_data.message);//its not a tumor

There's a lot flexibility in how to go about what you are after.  Hope I offered some insight.  

Doug Snyder

unread,
Mar 21, 2014, 6:55:11 PM3/21/14
to ang...@googlegroups.com
Hmmm ... it doesn't seem to be working that way.
I created a Node from the controller by calling the service's constructor:

The logging in my Node definition confirms it gets the input node_data to the constructor:

var node = nodeService.Node(node_data);

and that after the constructor runs this contains the node_data

function Node( data) {

console.log(data); 

this.node_data  = data; 

console.log(this); 


but when the constructor returns the Node object to the controller it is undefined and the functions
defined on Node fail.

It seems like it should behave the way you described but it doesn't in my code.
Can you think of something wrong that could make my code behave the way it is?
perhaps in the way I'm defining my service or controller?
I think I replicated this right from the docs, but since I don't understand how those definitions work,
maybe I did something wrong without knowing it.
Doug

Luke Kende

unread,
Mar 21, 2014, 8:28:50 PM3/21/14
to ang...@googlegroups.com
Can you put your code in a plunker? http://plnkr.co/

It will be easier to assist and share code together.


--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/HlbJiSQqPIQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages