0

How can I hold information in an array in javascript that I've retrieved from a text file for later use? I'm using it to place some HTML but also to react to the user. As of now I can place the HTML just fine using inline function calls, but I want that data to use later...

function get_words() {
    var words = new Array();
    var sylls = new Array();
    var csv_file = new Array(); // for word arrays

    $.get('terms.csv', function(data){
        csv_file = data.split('\n');
        // csv file is now in an array, split into seperate word array and syllable array
        for (var i = 0; i < csv_file.length; i++) {
            var both = csv_file[i].split(',');  // split at the comma
            words[i] = both[0]; // populate word array
            sylls[i] = both[1]; // populate syllable array
            put_word(words[i], sylls[i]);
        };
        check_resize();
    });
}

function put_word(word, sylls) {
    console.log(word);
    // place the words into 'words' div
    var divID = document.getElementById("words");   // grab 'words' div
    divID.innerHTML += "<span>" + word + "</span>" + "<sup>" + sylls + "</sup> ";
}

That's the code I have. I'd like it if words[] and sylls[] were accessible outside that get function.

EDIT: Let me be more clear (oops). It doesn't matter where I declare my arrays. The reason I know this is because I can put them at the top of my script (outside of a function) and at the end of get_words() try console.log(words) and it will be an empty array.

var words = new Array();
var sylls = new Array();
var csv_file = new Array(); // for word arrays

$(document).ready(function(){
    get_words();
});


function get_words() {


    $.get('terms.csv', function(data){
            csv_file = data.split('\n');
                // csv file is now in an array, split into seperate word array and syllable array
                for (var i = 0; i < csv_file.length; i++) {
                    var both = csv_file[i].split(',');  // split at the comma
                    words[i] = both[0]; // populate word array
                    sylls[i] = both[1]; // populate syllable array
                    //put_word(words[i], sylls[i]);
                };
                check_resize();
        });
    console.log(words);

}

EDIT: Can someone tell me where to put a callback??

function get_words() {


    $.get('terms.csv', function(data){
            csv_file = data.split('\n');
                // csv file is now in an array, split into seperate word array and syllable array
                for (var i = 0; i < csv_file.length; i++) {
                    var both = csv_file[i].split(',');  // split at the comma
                    words[i] = both[0]; // populate word array
                    sylls[i] = both[1]; // populate syllable array
                    //put_word(words[i], sylls[i]);
                };
        });

}

So... if I want to wait until after this file has been put into the array, then call another function, how do I do that?

Steve
  • 8,609
  • 6
  • 40
  • 54
prismspecs
  • 1,482
  • 6
  • 20
  • 35
  • 3
    Simply put the `words` and `sylls` instanciations outside the `get_words` function – Paul Rad Oct 02 '13 at 20:09
  • Do you mean outside of `get` or outside of `get_words`? – James Montagne Oct 02 '13 at 20:09
  • I'm not sure what you mean but here's a go, either to define the arrays outside of the function, and if this isn't what you mean, maybe you want to store the strings in some session like object, i'd suggest using a cookie if it's just JS – theBigChalk Oct 02 '13 at 20:11
  • They're already outside `$.get`. – Barmar Oct 02 '13 at 20:11
  • "I'd like it if words[] and sylls[] were accessible outside that get function." - They should be accessible outside of the `get` function, since they are declared above it... what error do you encounter that makes you believe they are not accessible? – Steve Oct 02 '13 at 20:11
  • He's trying to access it outside the scope of get_words(). – Tetsujin no Oni Oct 02 '13 at 20:12
  • 2
    Note that even if they're accessible outside "get_words", you still have to deal with the fact that `$.get()` is **asynchronous**. A call to "get_words" will return before the callback has run. What you're probably going to end up having to do is amend "get_words" so that you pass in a callback function. – Pointy Oct 02 '13 at 20:17
  • Pointy, thank you! What do you mean amend get_words so that I pass in a callback function? – prismspecs Oct 02 '13 at 20:24
  • Prism: see xtofl's answer. – Tetsujin no Oni Oct 02 '13 at 20:34

5 Answers5

1
var words = [];
var sylls = [];
function get_words() {
    $.get('terms.csv', function(data){
        // Clear the result arrays
        words = [];
        sylls = [];
        var csv_file = data.split('\n');
        // csv file is now in an array, split into seperate word array and syllable array
        for (var i = 0; i < csv_file.length; i++) {
            var both = csv_file[i].split(',');  // split at the comma
            words[i] = both[0]; // populate word array
            sylls[i] = both[1]; // populate syllable array
            put_word(words[i], sylls[i]);
        };
        check_resize();
    });
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • It doesn't matter where I place the arrays, they will come back as blank. – prismspecs Oct 02 '13 at 20:27
  • Are you looking at them right after calling `get_words`? Since it use AJAX, the assignment runs asynchronously, so the variables aren't updated when the function returns. – Barmar Oct 02 '13 at 20:29
  • Ah ok, so how do I ... make it useful? I mean, what good is it to me if I can't access the array I just created? – prismspecs Oct 02 '13 at 20:30
  • See the duplicate question I just linked to http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call – Barmar Oct 02 '13 at 20:32
  • I still don't see the solution. Is it '.done:' ? – prismspecs Oct 02 '13 at 20:47
0
var words = [], sylls = [], csv_file=[];
function get_words(){ ... }
function put_word(){ ... }

function needs_words_and_sylls(){ .... }
Tetsujin no Oni
  • 7,300
  • 2
  • 29
  • 46
  • It doesn't matter where I place the arrays, they will come back as blank. – prismspecs Oct 02 '13 at 20:28
  • They will not be blank when the success callback of $.get() finishes, assuming it fills them. Until that callback is done, they will be in an indeterminable state. – Tetsujin no Oni Oct 02 '13 at 20:33
  • So how do I do something only after $.get() finishes? No one can seem to give me an answer to that o_O – prismspecs Oct 02 '13 at 21:34
  • You put the call to the function you want to run at the end of your $.get() handler, or use the more complex notation of $.ajax and bind to the success and complete and error options there. – Tetsujin no Oni Oct 03 '13 at 13:21
0

In javascript scopes are created and binded into only the function which contains them.

For your case your variable words is created within the function get_words and will only be accessible inside get_words function. To allow two or more functions to access same scope, they have to be defined in the same scope.

Also for your case your both functions seems to be defined in global scope, so the variables that you want to be accessible to both your functions, needs to be defined in global scope also:

var words = new Array();
    var sylls = new Array();
    var csv_file = new Array(); // for word arrays

function get_words() {


    $.get('terms.csv', function(data){
        csv_file = data.split('\n');
        // csv file is now in an array, split into seperate word array and syllable array
        for (var i = 0; i < csv_file.length; i++) {
            var both = csv_file[i].split(',');  // split at the comma
            words[i] = both[0]; // populate word array
            sylls[i] = both[1]; // populate syllable array
            put_word(words[i], sylls[i]);
        };
        check_resize();
    });
}

function put_word(word, sylls) {
    console.log(word);
    // place the words into 'words' div
    var divID = document.getElementById("words");   // grab 'words' div
    divID.innerHTML += "<span>" + word + "</span>" + "<sup>" + sylls + "</sup> ";
}
Kemal Dağ
  • 2,743
  • 21
  • 27
0

There are a few things you can do, either move the variables out of the function like this:

var words = new Array();
var sylls = new Array();
var csv_file = new Array(); // for word arrays
function get_words() {
    //code here
}

Or you can just add the variable as a window object

function get_words() {
    window.words = new Array();
    window.sylls = new Array();
    window.csv_file = new Array(); // for word arrays
}

I also recall being able to just define the variable without the "var" and it becomes global just like window. Let me know if that works.

function get_words() {
    words = new Array();
    sylls = new Array();
    csv_file = new Array(); // for word arrays
}
Heath N
  • 533
  • 1
  • 5
  • 13
  • While #1 is probably helping the OP, I would caution about #2 and #3. #2 creates global objects, which might not be desirable in the OPs case. For all we know, his code snippet is wrapped in another function (like jQuery's `ready`), which would NOT create global variables. #3 is dangerous, because it may or may not create globals. If there is another `words` variable in the scope chain, it would be overwritten. – Steve Oct 02 '13 at 20:23
  • Well we are assuming that he knows about scope and would know not to overwrite variables within the same scope. #3 is not the ideal solution. Looks like the OP has updated his post, the issue I see now is that it seems he is calling `console.log(words);` outside of the `$(document).ready()`, naturally words will not exist when the console.log is called as console.log will run prior to the document ready. – Heath N Oct 10 '13 at 17:19
0

Since you're dealing with an asynchronous interface to read the data, you can only build further on that. So basically you would have to reverse your goal of 'bringing out the data' into 'bringing in the processing'.

You can inject the processing function into the reading function:

function get_words( process ) {
    ...
    $.get(...){ function(data){
       ...
       process(word, syllabs);
    }
}

function put_word(w, s) {
   ...
}

//this is where the action starts:
get_words( put_word );

An example: http://jsfiddle.net/xtofl/Qb867/

xtofl
  • 40,723
  • 12
  • 105
  • 192
  • Hmm I can't understand your code at all but asynchronous is definitely the keyword I needed. – prismspecs Oct 02 '13 at 20:29
  • I've never seen anything like this! It seems to be what I need, though. Thank you. So really it's a callback function? like function_first(function_second)? and that will execute the first and then the second? – prismspecs Oct 02 '13 at 20:53
  • Hmm it's still coming back undefined – prismspecs Oct 02 '13 at 21:18
  • @prismspecs: it's a _function_ passed in as an argument. This is very commonplace in a language like Javscript, and in other (true) functional languages like Scheme and Haskell. – xtofl Oct 03 '13 at 07:28