12

How can I fix the script below so that it will work EVERY TIME! Sometimes it works and sometimes it doesn't. Pro JQuery explains what causes this, but it doesn't talk about how to fix it. I am almost positive it has to do with the ajax ready state but I have no clue how to write it. The web shows about 99 different ways to write ajax and JQuery, its a bit overwhelming.

My goal is to create an HTML shell that can be filled with text from server based text files. For example: Let's say there is a text file on the server named AG and its contents is PF: PF-01, PF-02, PF-03, etc.. I want to pull this information and populate the HTML DOM before it is seen by the user. A was @#!#$*& golden with PHP, then found out my host has fopen() shut off. So here I am.

Thanks for you help.

JS - plantSeed.js

var pageExecute = {

fileContents:"Null",
pagePrefix:"Null",
slides:"Null",

init:function () {
    $.ajax({
      url: "./seeds/Ag.txt",
      success: function (data){
            pageExecute.fileContents = data;
      }
});
}
};

HTML - HEAD

<script type="text/javascript">
    pageExecute.init();
</script>

HTML - BODY

<script type="text/javascript"> alert(pageExecute.fileContents); </script>
atomSmasher
  • 1,465
  • 2
  • 15
  • 37
  • Any errors come up? Did you make sure that you include the .js file before `pageExecute.init();`. Also, don't rely on AJAX to load content, use server side also, if JS is disabled. – Novak Jul 21 '12 at 04:18
  • No errors at all, it actually works sometimes. I think it has to do with how fast the page loads, sometimes the ajax call is fast enough to beat the loading of the DOM, sometimes it isn't. I need to find a way to stop the dom from loading before the content is loaded. – atomSmasher Jul 21 '12 at 04:22

4 Answers4

14

Try this:

var pageExecute = {

    fileContents:"Null",
    pagePrefix:"Null",
    slides:"Null",

    init: function () {
        $.ajax({
            url: "./seeds/Ag.txt",
            async: false,
            success: function (data){
                pageExecute.fileContents = data;
            }
        });
    }
};
Novak
  • 2,760
  • 9
  • 42
  • 63
  • That did it. All this time it was one line! Thanks for you help. – atomSmasher Jul 21 '12 at 04:32
  • The next happened: You called `pageExecute.fileContents` before the AJAX `success` callback finished loading. `async: false` makes the browser to wait for the callback. Glad it worked out. – Novak Jul 21 '12 at 04:34
  • 4
    Doing synch requests is not AJAX and it is discouraged. You just need to process your data inside the success function (or delegate to another function, that is called inside success), remembering to to execute all this stuff after the fire of the domready event. – davidbuzatto Jul 21 '12 at 04:46
11

Try this:

HTML:

<div id="target"></div>

JavaScript:

$(function(){
    $( "#target" ).load( "pathToYourFile" );
});

In my example, the div will be filled with the file contents. Take a look at jQuery .load() function.

The "pathToYourFile" cand be any resource that contains the data you want to be loaded. Take a look at the load method documentation for more information about how to use it.

Edit: Other examples to get the value to be manipulated

Using $.get() function:

$(function(){
    $.get( "pathToYourFile", function( data ) {
        var resourceContent = data; // can be a global variable too...
        // process the content...
    });
});

Using $.ajax() function:

$(function(){
    $.ajax({
        url: "pathToYourFile",
        async: false,   // asynchronous request? (synchronous requests are discouraged...)
        cache: false,   // with this, you can force the browser to not make cache of the retrieved data
        dataType: "text",  // jQuery will infer this, but you can set explicitly
        success: function( data, textStatus, jqXHR ) {
            var resourceContent = data; // can be a global variable too...
            // process the content...
        }
    });
});

It is important to note that:

$(function(){
    // code...
});

Is the same as:

$(document).ready(function(){
    // code
});

And normally you need to use this syntax, since you would want that the DOM is ready to execute your JavaScript code.

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
davidbuzatto
  • 9,207
  • 1
  • 43
  • 50
  • This would almost work...However, I am bringing in a string with a ton of delimiters. The need to be stored into a variable and split before use. – atomSmasher Jul 21 '12 at 04:24
  • 1
    This load process needs to be synchronous or asynchronous? Just want to know to write an example. – davidbuzatto Jul 21 '12 at 04:27
  • Honestly, I am not sure. However, I think it can be synchronous because I want everything to wait until it loads the data. I think the problem is being caused by asynch – atomSmasher Jul 21 '12 at 04:28
  • 1
    There is the $.get() function that can be used, but it's default behavior is to be asynchronous. Wait, I will write some examples for you ;). – davidbuzatto Jul 21 '12 at 04:30
  • Wait! I got an answer! But you have been very helpful. – atomSmasher Jul 21 '12 at 04:32
  • 1
    You are welcome. Take a look, I updated my post with some code and some comments. I think that you need to understand some points that I said because they are useful. – davidbuzatto Jul 21 '12 at 04:49
3

Here's your issue: You've got a script tag in the body, which is asking for the AJAX data. Even if you were asking it to write the data to your shell, and not just spout it... ...that's your #1 issue.

Here's why:

AJAX is asynchronous. Okay, we know that already, but what does that mean?

Well, it means that it's going to go to the server and ask for the file. The server is going to go looking, and send it back. Then your computer is going to download the contents. When the contents are 100% downloaded, they'll be available to use.

...thing is...

Your program isn't waiting for that to happen. It's telling the server to take its time, and in the meantime it's going to keep doing what it's doing, and it's not going to think about the contents again, until it gets a call from the server.

Well, browsers are really freakin' fast when it comes to rendering HTML. Servers are really freakin' fast at serving static (plain-text/img/css/js) files, too.

So now you're in a race. Which will happen first? Will the server call back with the text, or will the browser hit the script tag that asks for the file contents?

Whichever one wins on that refresh is the one that will happen.

So how do you get around that? Callbacks.

Callbacks are a different way of thinking. In JavaScript, you perform a callback by giving the AJAX call a function to use, when the download is complete.

It'd be like calling somebody from a work-line, and saying: dial THIS extension to reach me, when you have an answer for me.

In jQuery, you'll use a parameter called "success" in the AJAX call. Make success : function (data) { doSomething(data); } a part of that object that you're passing into the AJAX call. When the file downloads, as soon as it downloads, jQuery will pass the results into the success function you gave it, which will do whatever it's made to do, or call whatever functions it was made to call.

Give it a try. It sure beats racing to see which downloads first.

Norguard
  • 26,167
  • 5
  • 41
  • 49
1

I recommend not to use url: "./seeds/Ag.txt",, to target a file directly. Instead, use a server side script llike PHP to open the file and return the data, either in plane format or in JSON format.

You may find a tutorial to open files here: http://www.tizag.com/phpT/fileread.php

Alfred
  • 21,058
  • 61
  • 167
  • 249