2

I am reading content of a local file using jquery and I get undefined.

I feel the problem is related to synchronization of URL loading. But I don't have any idea about how to fix this code:

function url_content(url)
{
    var content;
    $.get(url,function( data ) {content=data});
    return content;
}


var content=url_content("local_templates/template1.html");
alert(content);
barej
  • 1,330
  • 3
  • 25
  • 56

3 Answers3

6

Its because of the asynchronous nature of javascript. You have to wait for the data to come back before you can use it. You would need to do something like this:

function url_content(url){
    return $.get(url);
}


url_content("local_templates/template1.html").success(function(data){ 
  alert(data);
});

or just

$.get("local_templates/template1.html").success(function(data){ 
  alert(data);
  doSomeStuffWithTheResult(data);
});


function doSomeStuffWithTheResult(content) {
  // code that depends on content goes here...
}

If you absolutely must keep in synchronous you can do this(NOT RECOMMENDED)

function getRemote(remote_url) {
    return $.ajax({
        type: "GET",
        url: remote_url,
        async: false
    }).responseText;
}

jQuery: Performing synchronous AJAX requests

Community
  • 1
  • 1
Ryan
  • 5,845
  • 32
  • 27
  • The continue of process needs the result. How can I halt execution of the rest of commands until the data is ready? btw, the URL is local and I have no worry about waiting. – barej Aug 23 '15 at 04:41
  • thanks, but is there any way to put the waiting process inside function to stop bothering programmer? – barej Aug 23 '15 at 04:46
  • 1
    You used to be able to set `async: false` but I think that is deprecated so I wouldn't do that. Callbacks are very common in javascript especially with ajax and its probably better to embrace them rather that fight it. – Ryan Aug 23 '15 at 04:49
  • I do not use to write `js`. I uesd to write programs in `PHP` and `C++`. such process is very bizarre to me. I look for something similar to `CURL` – barej Aug 23 '15 at 04:54
  • Any reason to avoid `synchronous AJAX`? are you worried about page hangs? – barej Aug 23 '15 at 04:57
  • Its considered bad practice, its deprecated, bad for performance, bad user experience, etc. etc. – Ryan Aug 23 '15 at 04:58
  • btw, your method shows `[object XMLDocument]` any way to take `responseText` out of it? – barej Aug 23 '15 at 05:02
  • What are you doing to see `[object XMLDocument]`? If I `console.log(getRemote('/path/to/html'))` I see the content of the html file. – Ryan Aug 23 '15 at 05:07
  • `getRemote` works perfect. The `$.get` gives me that. – barej Aug 23 '15 at 05:11
  • Which browser? Works okay in chrome and FF for me. – Ryan Aug 23 '15 at 05:16
  • using FF under ubuntu. `$.get("local_templates/template1.html").success(function(data){console.log(data);})` gives me no response. as if success is never run – barej Aug 23 '15 at 05:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/87675/discussion-between-ryan-and-barej). – Ryan Aug 23 '15 at 05:26
  • How to deal with Cross Origin Policy. – Liaqat A. Mar 24 '23 at 05:57
5

Asynchronous vs Synchronous

The "A" in "Ajax" is for "Asynchronous". The underlying meaning of this word was hard to figure out for me, I know it can take some time to become familiar with, but it's a critical subject in modern web development and computing in general, hence it's worth a little effort.

Most of the time your code runs in a synchronous way, thus you don't have to worry about whether your environment is ready or not. Considering the following code, it's obvious that "v" is ready for being used at the time you need it, you don't have to wait for it to be initialized.

var v = 1;     // no delay during initialization
var u = v + 1; // you can use "v" immediately

Even if there was a delay at this point, a synchronous processing would wait for the instruction to be done before executing the next line. Hence, you can be sure that "v" will be ready when you'll need it. Now, let's see how this code behaves if we introduce an asynchronous task.

function ajax (url) {
    // 1. go to url asynchronously
    // 2. bring back the value
    // 3. return the value
};
var v = ajax('mywebsite.com'); // undefined
var u = v + 1; // "v" is not ready -> NaN

The way the tasks are numbered reflects what's going on in your mind, but it's not correct, actually 3 happens before 2. Roughly speaking, ajax() won't get the value fast enough and returns before the first task completes, hence, the value is not available and the program fails.

More precisely, the program starts talking to a remote computer as soon as ajax() is called. Such a task can last a couple of seconds, but the program is aware of its asynchronous nature, hence, it doesn't wait for the result and jumps to the next line immediately.

Now I think you should better understand what's going on. The main point is that a program isn't necessarily executed in a single flow, there might be some tasks executed apart from the rest, in parallel. If you are still confused, take some time to think of it before going further :-)

How to deal with asynchronous tasks ?

So, how to avoid crashing your program while performing asynchronous tasks ? Using callbacks. A callback is a function which is passed to another function as a parameter and called internally. Let's see how to fix the previous code block with a callback :

function ajax (url, callback) {
    // 1. go to url asynchronously
    // 2. bring the value
    // 3. when previous tasks done, do callback(value)
};
ajax('mywebsite.com', function (value) {
    var v = value;
    var u = v + 1;
});

To fully understand how it works, you need to know that there is an internal mechanism which acts as a middle man between your program and the remote computer. As soon as the response of the remote computer is available, this mechanism calls the callback function.

Well, I think it's enough for now, I won't bother you no more ;-) For details you should browse jQuery's docs on Ajax, it can be a good place to start. As a conclusion, here is a possible implementation of ajax() (not bullet proof). Enjoy.

function ajax (url, callback) {
    var req = new XMLHttpRequest();
    req.open('GET', url, true); // true = asynchronous
    req.onload = function () {
        var value = JSON.parse(this.responseText);
        callback(value);
    };
    req.send(null);
}

Additional stuffs (click to zoom)

Synchronous : the main flow is paused during remote queries.

Asynchronous : the main flow keeps going during remote queries.

4

".success" might not work and result in an error, try with ".then":

  var url="local_templates/template1.html";
  $.get(url).then(function(data){ alert(data); });