1

I want to make ajax call to my server with array value and sting parameters.

This is my function I am using in my page.

var globalArray = [];

function submit() {
    var string_MyVal, jsonBody, string_MyVal1, string_MyVal2, string_MyNameVal, string_MyNameDesc, string_MyNameFlag;

    string_MyVal1 = 150;    
    string_MyVal = "sel.html";
    string_MyVal2 = "string_MyVal2";
    string_MyNameVal = "string_MyNameVal";
    string_MyNameDesc ="string_MyNameDesc";
    string_MyNameFlag =  "private"; 

    jsonBody = 'storedSelections=' + globalArray + 
                '&string_MyVal='+ string_MyVal + 
                '&string_MyVal1='+ string_MyVal1 +
                '&string_MyVal2='+ string_MyVal2 + 
                '&string_MyNameVal=' + string_MyNameVal + 
                '&string_MyNameDesc='+ string_MyNameDesc + 
                '&string_MyNameFlag=' + string_MyNameFlag;

    $.ajax({
        async : false,
        type : "POST",
        url : 'http://example.com:8080/myApp/DataServlet',
        data : jsonBody,
        success : function(data) {
            setToken(data);
        },
        error : function(data, status, er) {
            alert("error: " + data + " status: " + status + " er:" + er);
        }
    });
}

In my servlet this globalArray comes as only "object object". There is more contents in that array..

how to pass this array and string values to my servlet.

I know to use JSON.stringify solved this,

var selections = JSON.stringify(globalSelection);
alert(selections

This works and the data is shown as below,

[{"range":{},"type":3,"rCollection":[{"range":{},"node":{},"tagName":"P","tagIndex":2,"data":"lot%20","nodeType":3,"sIdx":14,"eIdx":18,"fontColor":"yellow","bgColor":"green"}],"textContent":"lot%20","anchorNode":{},"focusNode":{},"selectionId":181862,"yPOS":0}]

But this wont support safari and iOS.

Can anyone assist here how to pass my array value to servlet along with string values in same ajax call.

EDIT:

This is the update I tried,

function textSelection(range, anchorNode, focusNode) {
    this.range = range;
    this.type = 3;
    this.rCollection = [];
    this.textContent = encodeURI(range.toString());
    this.anchorNode = anchorNode;
    this.focusNode = focusNode;
    this.selectionId = getRandom();
    this.yPOS = getYPOS();

    this.getTagName = function(range) {
        var el = range.startContainer.parentNode;
        return el;
    }
    this.getTagIndex = function(el) {
        var index = $(el.tagName).index(el);
        return index;
    }

    this.simpleText = function(node, range) {
        if (!node)
            var entry = this.createEntry(this.anchorNode, this.range);
        else
            var entry = this.createEntry(node, range);
        this.rCollection.push(entry);
        this.highlight(this.rCollection[0].range);
        this.crossIndexCalc();
        textSelection._t_list.push(this);
        pushto_G_FactualEntry(this);
    }

    this.compositeText = function() {
        this.findSelectionDirection();
        var flag = this.splitRanges(this.anchorNode, this.focusNode,
                this.range.startOffset, this.range.endOffset);
        if (flag == 0) {
            for (j in this.rCollection) {
                this.highlight(this.rCollection[j].range);
            }
        }
        this.crossIndexCalc();
        textSelection._t_list.push(this);
        pushto_G_FactualEntry(this);
    }

    this.toJSON = function() { 
    return  {range: this.range};
}

}

In globalSelection, I have the elements of above textSelection. I added toJSON to this as suggested.

Now I am getting the result in console as below,

[{"range":{}}]

It comes as empty value...

  • "But this wont support safari and iOS" — What does that mean? Do you get an error? Do you get the data in a format you don't expect? Why aren't you URL encoding your data? – Quentin Apr 15 '16 at 07:18
  • "TypeError: JSON>stringify cannot serialize cyclic structures" This is the error in safari console. –  Apr 15 '16 at 07:29
  • How about not having a cyclical data structure in the first place then? – Quentin Apr 15 '16 at 07:32
  • You can define a toJSON() method in your object to tackle this problem. – TOAOGG Apr 15 '16 at 07:32
  • Create an empty object, add the members you need, use a toJSON() method to serialize it and call JSON.stringify() on this object. – TOAOGG Apr 15 '16 at 07:34
  • @TOAOGG, if we do the toJSON, then sending this as parameter along with strings. can you pls elaborate.. –  Apr 15 '16 at 07:34
  • Please replace the semicolons in the returned object with commas. – TOAOGG Apr 15 '16 at 11:08
  • P.S.: You will get undefined if you do this: var globalSelection = textSelection(); instead you need to do this: var globalSelection = new textSelection(); – TOAOGG Apr 15 '16 at 11:10

2 Answers2

2

Javascript offers methods for serialization:

toJSON()

This function is used to define what should be part of the serialization. Basically you can create a clone of the object you want to serialize excluding cyclic dependencies or data that should not be send to the server.

More information on this behaviour can be found here: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior

JSON.stringify()

This function calls toJSON() and serializes the returned object.

Example:

var objectToSend = {};
objectToSend.varX = 5;
objectToSend.varY = 10;
objectToSend.toJSON = function() { return {varX: this.varX}; }
var jsonString = JSON.stringify(objectToSend);

The result will be:

"{"varX":5}"
TOAOGG
  • 392
  • 1
  • 10
-1

If you are writing both the client and server implementations then I would advise creating your data as a JSON object then using base64 encoding to convert the JSON object to a string that you can send as one encoded parameter:

    encodededjson=(BASE 64 encoded JSON here)

Then on the server you just use the equivalent base 64 decode routine to translate the encoded data back to JSON. So you use:

    var strJSON = JSON.stringify(globalSelection);

And pass the result of this to the base64 encode routine, then use the result from that to build your Post:

    var strJSON = JSON.stringify(globalSelection);
       ,strEncoded = Base64.encodeBase64(new String(strJSON.getBytes()))
       ,strPost = "datatopost=" + strEncoded;
SPlatten
  • 5,334
  • 11
  • 57
  • 128
  • SPlatten thanks for your answer.. Can you pls assist how to do that in my code... As I am new to this hope you can help.. –  Apr 15 '16 at 07:28
  • Can you tell me what the server backend is, node, apache, IIS ? – SPlatten Apr 15 '16 at 07:30
  • That (a) won't work since the problem is that JSON.stringify is failing for the data in the question and (b) is a really weird idea since there is a standard for encoding strings into form encoded data which has a native implementation in JS (`encodeURIComponent`) and will be handled automatically by the form data parser on the server. – Quentin Apr 15 '16 at 07:31
  • back end is java servlet –  Apr 15 '16 at 07:32
  • I've used this technique myself many times and it works. encoding as base64 gets around the need to url encode the data. For information on base64 encoding and decoding in java: http://stackoverflow.com/questions/19743851/base64-java-encode-and-decode-a-string – SPlatten Apr 15 '16 at 07:33
  • 1
    @SPlatten — Yes it does, but "getting around" URL encoding the data is not desirable. URL encoding is better than base64 encoding and then having to manually base64 decode the result. And as I said, it doesn't solve the problem in the question, which is that JSON.stringify is failing. You can't base64 encode (or URL encode) a string that you can't generate. – Quentin Apr 15 '16 at 07:37