0

I'm using RequireJS while prototyping an application. I'm "faking" a real database by loading a json file via ajax.

I have several modules that need this json file, which I noticed results in multiple http requests. Since I'm already using RequireJS, I thought to myself "hey, why not load this json file as another module". Since a module can return an object, it seemed reasonable.

So I tried this:

// data.js
define(function(require){
  const $ = require('jquery')
  var data = {}
  $.getJSON('/path/to/data.json', function(json_data){
    data = json_data
  })
  // this does not work because getJSON is async
  return data 
})

// some_module.js
define(function(require){
  const my_data = require('data')

  console.log(data) // undefined, but want it to be an object
})

I understand why what I'm doing is not working. I'm not sure what the best way to actually do this would be though.

Things I don't want to do:

  • Change getJSON to async: false
  • add a while (data == null) {} before trying to return data

Is there an AMD-y want to accomplish what I'm trying to do? I'm sure there's a better approach here.

Edit

I just tried this. It works, but I'm not sure if this is a good or terrible idea:

// in data.js
return $.getJSON('/path/to/data.json')

// in some_module.js
const my_data = require('data')
my_data.then(function(){
  console.log(my_data.responseText)
  // do stuff with my_data.responseText
})

My concern is (1) browser support (this is a "promise", right?) and (2) if multiple modules do this at the same time, will it explode.

Scribblemacher
  • 1,518
  • 1
  • 16
  • 31
  • Using promises is a good idea. – SLaks Sep 14 '17 at 20:26
  • My edit strangely worked in IE, even though IE does not support promises. It actually looks like I was intending to use a promise but (because my data was going into a JQuery object), using `.then()` actually invoked JQuery's [`deferred.then()`](https://api.jquery.com/deferred.then/) method, hence why it worked in IE. – Scribblemacher Sep 15 '17 at 12:23
  • Yes; jQuery includes its own promise implementation (`Deferred`) and never uses native promises. – SLaks Sep 15 '17 at 14:43

1 Answers1

0

Because this question is specifically referring to using JQuery, you can actually do this without a native promise using JQuery's deferred.then().

// in data.js
return $.getJSON('/path/to/data.json')

// in some_module.js
const my_data = require('data') // this is a JQuery object
// using JQuery's .then(), not a promise
my_data.then(function(){
  console.log(my_data.responseText)
  // do stuff with my_data.responseText
})

Based on the description of then() in JQuery's docs, it looks like this is using a promise behind the scenes:

As of jQuery 1.8, the deferred.then() method returns a new promise that can filter the status and values of a deferred through a function, replacing the now-deprecated deferred.pipe() method. [...]

Callbacks are executed in the order they were added. Since deferred.then returns a Promise, other methods of the Promise object can be chained to this one, including additional .then() methods.

Since JQuery's .then() does work in IE, I guess they are polyfilling the promise for IE behind the scenes.

Community
  • 1
  • 1
Scribblemacher
  • 1,518
  • 1
  • 16
  • 31