AirWolf
AirWolf

Reputation: 597

javascript array to array

i downloaded a grid: ParamQuery grid and i need to add items to it, im quite new to javascript but as i see it uses a variable data that keeps its records in arrays array like this:

var data = [['hello','byebye']]

i need to add those records from a ini file so for now i have a code like this:

$(function () {

var allText =[];
var allTextLines = [];
var Lines = [];
var txtFile = new XMLHttpRequest();
var linenumber = 0; 
var data = new Array();

txtFile.open("GET", "automaticlang_EN.ini", true);
allText = txtFile.responseText;
txtFile.onreadystatechange = function()
{
    if (txtFile.readyState == 4)
    {

              // Makes sure it's found the file.
                allText = txtFile.responseText;
                allTextLines = allText.split(/\r\n|\n/);
                var data = new Array([allTextLines]);

                console.log(data[0]);
            } else { 
            }

    }
txtFile.send(null)
//console.log(data);


//var data = [['hello','byebye']] //this works


    var obj = { width: 700, height: 700, title: "Translation  Grid",resizable:true,draggable:true };
    obj.colModel = [{ title: "ID", width: 100, dataType: "string" },
    { title: "Translation", width: 200, dataType: "string" }];
    obj.dataModel = { data: data };
    $("#grid_array").pqGrid(obj);

});

and i doesnt give me the results what im doing wrong?

Upvotes: 1

Views: 233

Answers (2)

Michael Geary
Michael Geary

Reputation: 28870

The reason your code isn't working is that you are trying to use your data variable outside the XMLHttpRequest callback. The code where you try to use data is run immediately after you issue the GET request, not after the value is returned from the server.

So the main thing you need to fix is to do the pqGrid() setup inside the XMLHttpRequest callback.

Just for fun, I tuned up a few other things for you:

  • Since you're using jQuery, you can use $.ajax() instead of the cumbersome XMLHttpRequest.
  • Added a $.trim(allText) call to strip out any leading or trailing whitespace. In particular this will remove any trailing newlines so you won't have an extra empty string in your array if the last line has a newline at the end.
  • Used a slightly simpler regular expression for the .split().
  • Used just an array literal instead of new Array. As nkron pointed out, having both the new Array and the array literal was giving you one more level of nested array than you wanted. And array literals are almost always more readable than new Array.
  • Rearranged the setup of the pqGrid settings object. There's nothing wrong with the way you were doing it (except for the very long lines), just showing another way to set it up here.
  • Cleaned up the indentation and long lines.
$(function() {
    $.ajax({
        url: "automaticlang_EN.ini",
        dataType: "text"
    }).done( function( allText ) {
        var allTextLines = $.trim(allText).split(/\r?\n/);
        var data = [ allTextLines ];

        $("#grid_array").pqGrid({
            width: 700,
            height: 700,
            title: "Translation  Grid",
            resizable: true,
            draggable: true,
            colModel: [
                {
                    title: "ID",
                    width: 100,
                    dataType: "string"
                }, {
                    title: "Translation",
                    width: 200,
                    dataType: "string"
                }
            ],
            dataModel: {
                data: data
            }
        });
    });
});

Upvotes: 1

nkron
nkron

Reputation: 19791

I think you are close. The 3rd parameter to JavaScript's XMLHttpRequest open() method is whether the data is requested asynchronously or not. true means the download will start and then some time later finish with the onreadystatechange callback called at the end of the download.

You have a couple options here. You can pass in false instead of true and keep your data processing code after the send() call since that will cause the download to finish before send() returns. This is generally frowned upon because it causes the browser to stop doing any processing until the download completes.

Your other option would be to keep the download asynchronous and move the data processing code into the onreadystatechange callback. This would allow the browser to continue to process other events while the file is downloading.

Another issue I see is that you say var data variable in the outer function and in the onreadystatechange function. This will cause the data variable in the inner function to be a different variable than the outer one. So when you set the inner data, its value will be lost when the function returns. To fix this, remove the var from before the inner function's data so the inner function uses the data defined by the outer function.

Finally, it looks like you are wrapping the data in too many arrays. Putting one [] around the data should be enough.

To recap, here are the two options. Use synchronous download & fix the data scope:

$(function () {
  var txtFile = new XMLHttpRequest();
  var data;

  txtFile.open("GET", "automaticlang_EN.ini", /* async = */ false);

  txtFile.onreadystatechange = function() {
    if (txtFile.readyState === 4) {   
      // Makes sure it's found the file.
      var allText = txtFile.responseText;
      var allTextLines = allText.split(/\r\n|\n/);
      data = [allTextLines];
    }
  };

  txtFile.send();

  var obj = { width: 700, height: 700, title: "Translation Grid",resizable:true,draggable:true };
  obj.colModel = [{ title: "ID", width: 100, dataType: "string" },
                  { title: "Translation", width: 200, dataType: "string" }];
  obj.dataModel = { data: data };
  $("#grid_array").pqGrid(obj);  
});

Use asynchronous and move the processing into onreadystatechange:

$(function () {
  var txtFile = new XMLHttpRequest();

  txtFile.open("GET", "automaticlang_EN.ini", /* async = */ true);

  txtFile.onreadystatechange = function() {
    if (txtFile.readyState === 4) {   
      // Makes sure it's found the file.
      var allText = txtFile.responseText;
      var allTextLines = allText.split(/\r\n|\n/);
      var data = [allTextLines];

      var obj = { width: 700, height: 700, title: "Translation Grid",resizable:true,draggable:true };
      obj.colModel = [{ title: "ID", width: 100, dataType: "string" },
                      { title: "Translation", width: 200, dataType: "string" }];
      obj.dataModel = { data: data };
      $("#grid_array").pqGrid(obj);  
    }
  };

  txtFile.send();
});

Upvotes: 1

Related Questions