2

I have javascript getter setter class

function UserContext() {
    var category_id;
    var biller_id;

    this.get_category_id = function () {
        return category_id;
    }
    this.set_category_id = function (value) {
        category_id = value;
    }

    this.get_biller_id = function () {
        return biller_id;
    }
    this.set_biller_id = function (value) {
        biller_id = value;
    }
}

I am creating object of this class in jquery click event

var contextObj = new UserContext();
contextObj.set_category_id('SOME VALUE');
contextObj.set_biller_id('65');

I have similar class in c#

public class CustomerDTO
{
    public string category_id { get; set; }
    public string biller_id{ get; set; }
}

And one asp:hidden element

<asp:HiddenField ID="hdnValue" ClientIDMode="Static" runat="server" />

What i want to achieve

  1. Assign contextObj to asp:hidden element by serializing (may be in json format)
  2. In Code behind get this object desrailize it and assign the values to its respective c# class i.e CustomerDTO
  3. So that i can access all these values through out all pages request (By Passing this object in Server.Transfer request)

To serialize object i tried this

console.log(JSON.stringify(contextObj));

But it prints nothing. I want value to get printed so that i can assign to hidden variable

Yuliam Chandra
  • 14,494
  • 12
  • 52
  • 67
Shaggy
  • 5,422
  • 28
  • 98
  • 163

4 Answers4

6

You have wrong syntax. The problem is that your variables are private, and they will not be accessible by the stringify() function. In fact if you try to access a private variable directly you will get 'undefined'.

Serialization works only on the public members, and that makes sense, since the private variables are not accessible.

This should work as a quick hack, but it makes your variables public (as soon as you use this.category_id = value), so it is breaking encapsulation which is not good:

function UserContext() {
  this.category_id;
  this.biller_id;

  this.get_category_id = function() {
    return this.category_id;
  }
  this.set_category_id = function(value) {
    this.category_id = value;
  }

  this.get_biller_id = function() {
    return this.biller_id;
  }
  this.set_biller_id = function(value) {
    this.biller_id = value;
  }
}

var contextObj = new UserContext();
contextObj.set_category_id('SOME VALUE');
contextObj.set_biller_id('65');

alert(JSON.stringify(contextObj));
A better approach would be to keep category_id and biller_id really private, and still be able to serialize your object. You con do that by implementing the ToJson() method in your object, and specifying explicitly what you want to serialize:
function UserContext() {
  var category_id;
  var biller_id;

  this.get_category_id = function() {
    return category_id;
  }
  this.set_category_id = function(value) {
    category_id = value;
  }

  this.get_biller_id = function() {
    return biller_id;
  }
  this.set_biller_id = function(value) {
    biller_id = value;
  }
  
  this.toJSON = function() {
        return {
            "category_id": category_id,
            "biller_id": biller_id
        };
    };
}

var contextObj = new UserContext();
contextObj.set_category_id('SOME VALUE');
contextObj.set_biller_id('65');

alert(JSON.stringify(contextObj));

As a result, your variables are only accessible through your setters and getters, and you are also able to serialize your object using your private members! i would call that a Win-Win situation!

Faris Zacina
  • 14,056
  • 7
  • 62
  • 75
  • 1
    Why do you change the accessibility of those private variables that he wanted ? – Royi Namir Sep 26 '14 at 08:02
  • It works without `=''` as well so why to include that ? – Shaggy Sep 26 '14 at 08:05
  • Default values. You can omit that if not needed. I will update the answer. – Faris Zacina Sep 26 '14 at 08:07
  • Notice: Without default value `JSON.stringify` may not return variables. – Cyrbil Sep 26 '14 at 08:12
  • 1
    +1 for the `toJSON()` method as it the best approach trading with the original constraints of the OP. And also because I learn that there is snippet now in SO :). Edit: For your first piece of code, see Royi answer's discution. You are using 2 variables for one. – Cyrbil Sep 26 '14 at 08:44
1

Javascript serializer does not use setter and getter as C# does. To have your attributes converted they need to be exposed and set into your class.

function UserContext() {
    this.category_id = null;
    this.biller_id = null;

    this.get_category_id = function () {
        return category_id;
    }
    this.set_category_id = function (value) {
        category_id = value;
    }

    this.get_biller_id = function () {
        return biller_id;
    }
    this.set_biller_id = function (value) {
        biller_id = value;
    }
}

then it should add attributes correctly to your json:

var contextObj = new UserContext();
console.log(JSON.stringify(contextObj ));
Cyrbil
  • 6,341
  • 1
  • 24
  • 40
  • But this will also lose the private accebility. – Royi Namir Sep 26 '14 at 08:19
  • There is no such thing as privacy accessibility in javascript. As in python everything is exposed and it's common to declare a variables as private simply by renaming it with an underscore `_variable`. There is some hackish ways to achieve some privacy access but it's never really private and not even a good practice imo. Your first class declaration was correct, but if you want to serialize it won't fit. – Cyrbil Sep 26 '14 at 08:22
  • @Royi: Better wait Ecma6 with a real chance to have [private variable](http://wiki.ecmascript.org/doku.php?id=strawman%3aprivate_names). – Cyrbil Sep 26 '14 at 08:28
  • I meant : _There is no such thing as privacy accessibility in javascrip_ is a wrong statement. no need to wait to any Ecma 6. the example I gave you provide **private** access – Royi Namir Sep 26 '14 at 08:29
  • @Royi: You got a point, but comparing to other langage it's more like a hidden variable than private. Javascript have less rigor than many other langage and is lacking many oop paradigm. Anyway, topic solved, let's move on. – Cyrbil Sep 26 '14 at 08:40
  • Check out Douglas Crockford article about private variables: http://javascript.crockford.com/private.html – Faris Zacina Sep 26 '14 at 08:48
1

Change your code to :

function UserContext() {
    var category_id;
    var biller_id;

    this.get_category_id = function () {
        return this.category_id;
    }
    this.set_category_id = function (value) {
        this.category_id = value;
    }

    this.get_biller_id = function () {
        return this.biller_id;
    }
    this.set_biller_id = function (value) {
        this.biller_id = value;
    }
    }

Don't do this as other suggested :

 this.category_id = "";
  this.biller_id = "";

These meant to be private. keep them like that.

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • That is wrong, you end up having `category_id` AND `this.category_id` in your object. There is not point of doing this. – Cyrbil Sep 26 '14 at 08:03
  • @cyrbil no. look at the console. you dont see - and should see those private – Royi Namir Sep 26 '14 at 08:05
  • @Shaggy it work indeed. But not the way you might expect. There is two differents variables here. Try putting a value like `var category_id = "test";` and then accessing by the getter... – Cyrbil Sep 26 '14 at 08:09
  • @cyrbil yes . didnt noticed. that. fixed. – Royi Namir Sep 26 '14 at 08:15
  • @Royi and now you can't serialize it. Because you do not expose your variables outside of the function. Only getters and setters are exposed here, and javascript don't serialize them. – Cyrbil Sep 26 '14 at 08:17
  • @RoyiNamir No it didnt worked if you removed `this` keyword. check again ! It is the same code snippet which i pasted in Ques. – Shaggy Sep 26 '14 at 08:18
  • Revereted to the original answer of mine. this way it also keeps privates. – Royi Namir Sep 26 '14 at 08:23
0
I think this way of function definition looks fine
function UserContext() {
  var category_id = "";
  var biller_id = "";

  this.get_category_id = function() {
    return this.category_id;
  }
  this.set_category_id = function(value) {
    this.category_id = value;
  }

  this.get_biller_id = function() {
    return this.biller_id;
  }

alert(JSON.stringify(contextObj));//now check in alert for out put
  this.set_biller_id = function(value) {
    this.biller_id = value;
  }
}


var contextObj = new UserContext();
contextObj.set_category_id('Delhi');
contextObj.set_biller_id('43');
clarifier
  • 119
  • 1
  • 13