3

How can I access a JSON array from a PHP variable in an external JavaScript file without creating a global variable?

I have a PHP variable $customers that contains a json_encoded array:

$customers = [{"id":"12","name":"Abe Adams"},{"id":"17","name":"Bill Brown"}]

I want to use the contents of the array in a jQuery UI Autocomplete text input.

Rather than make an Ajax request for the autocomplete options, I'd prefer to use the values in the $customers array, which is passed in and ready to go when the user arrives at the page.

I know I can pass the contents of $customers to a JavaScript variable prior to loading the external JavaScript file:

<script>var customers = <?php echo $customers; ?></script>
<script src="external.js"></script>

But this requires creating a global JavaScript variable.

Is there a better way to access the $customers array from my external JS file?


This question has been asked several times previously:

Question: Access PHP var from external javascript file Accepted Answer: Create global var

Question: Pass vars from php to js without ajax Top Answer: Use Ajax

Question: php file send variable to .js external file Top Answer: Use Ajax

Question: Reading a PHP file variables from external JS Top Answer: Use eval

Question: Return JSON data from PHP, and use it using Javascript Accepted Answer: Create global var

2
  • If you are using autocomplete plugin, then you not need to store that json, set source to autocomplete and it will retrieve data. Commented Jun 2, 2012 at 5:38
  • @thecodeparadox - Could you show me what you mean? Not seeing anything in the jQuery docs on setting source to autocomplete and not sure how it would know where to look. Would be brilliant if this does work. Commented Jun 2, 2012 at 5:47

3 Answers 3

2

No, you can't do that without making external.js be a dynamically generated. You can however improve your strategy a little. Instead of having a global named customers have a global object for attaching all your global variables too:

window.Globals = {};
Globals.customers = <?php echo $customers; ?>;
Globals.something_else = <?php echo $something_else; ?>

Don't name it Globals though. Name it something specific to your company or web app/site. This way you will greatly reduce the risk of conflicting variable names with any external scripts, since you only have one global variable you use, and it is named after something specific to your site.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks - I like this strategy for managing globals and don't think I'd seen it done this way before. Will peruse some of your other responses as well - I'm guessing you've posted other helpful JS tricks.
You're welcome @cantera25, and feel free to look around :) Although I don't think of have any posts that are specifically JS tricks rather than answers to specific questions.
1

You could also use a requirejs "pattern":

external.js:

define([], {
    init: function (customerData) {
        ... all your setup
    }
});

On page:

require(['external'], function (externalSetupFile) {
    var customers = <?php echo $customers?>;
    externalSetupFile.init(customers);
});

A big benefit to (in general) having some sort of "init" method that fires off the enhancement of the site is that you can do things like this. For example:

Application = {
   init: function (bootstrapData) {
       UserModel.create(bootstrapData.userModelData); //for example 
       this.config = bootstrapData;
       this.setupUI();
   },
   setupUI: function () {
      //setup autocomplete and the like
      $("#someEl").autocomplete(this.config.customers);
   }
}

An even better part of this is that you can split up what you're doing into small sections, which makes testing and debugging a heck of a lot easier.

3 Comments

Thanks Stephen - this is awesome. I've only worked with RequireJS a little bit - do you know where this pattern is documented or any tutorials that explain it? Also, what does the empty array signify in the define() argument?
This is kind of a mix-mash of various things I've picked up on from working with single page applications. The empty array isn't necessary.. I add it out of habit, because most modules I work on are interdependent to some extent. Anyway, the 'pattern' is really more something you can pick up from Java and the like.. have a "main" function that gets the application booted and running. That way you can control specifically when the thing starts and what it starts with (i.e. getting data from the page vs an ajax call vs a jsonp call, etc).
I backtracked through some of my books and couldn't nail down a specific example - but if you're interested I would highly recommend amazon.com/JavaScript-Patterns-ebook/dp/B0046RERXE (it gives some good food for thought)
0

I think you can implement this, if you're trying with autocomplete plugin.

$("#some_input_field").autocomplete("search.php", {
    // your code
});

or you can do also

$( "#some_input_field" ).autocomplete({
     source: "search.php",
     // some other code
});

Here source.php will replace with the url from where you load data.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.