0

I am defining dynamic variables in a way that works fine in Chrome:

id = parent.data('parent_id')
$.ajax
  ...
  success: (res, status, xhr) ->
    alert(res.results.slice(0,4)) # gives '[object Object],[object Object],[object Object],[object Object]' in Chrome and FF
    window[id] = res.results.slice(0,4) # works fine to set in Chrome
    console.log(window[id]) # gives correct object in Chrome, 'undefined' in FF
  ...

However, when I try to use the same syntax in Firefox, I get TypeError: obj is undefined in the FF console and console.log(window[id]) writes "undefined" as well.

What is the correct approach/syntax to get this working in both Chrome and Firefox?

EDIT

alert(res.results.slice(0,4)) gives [object Object],[object Object],[object Object],[object Object] in both Chrome and Firefox right before I try to define window[id], so the object has been defined at that point.

EDIT 2

Example found here: http://jsfiddle.net/8Wk9J/. Works in Chrome but gives undefined in Firefox

Tyler
  • 11,272
  • 9
  • 65
  • 105
  • possible duplicate of [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – elclanrs Jan 17 '14 at 18:25
  • @elclanrs this has nothing to do with the question you linked to or with which is faster. Please read the question instead of blindly submitting a close vote. – Tyler Jan 17 '14 at 18:26
  • The concept works fine in chrome: http://jsfiddle.net/nFe89/. Are you sure `res.results.slice(0,4)` isn't `undefined`? – Jason P Jan 17 '14 at 18:29
  • I have it working in Chrome already, my question is about what will work in Chrome and Firefox both – Tyler Jan 17 '14 at 18:31
  • @tyler Sorry, got them mixed up. But my fiddle works for me in firefox as well. – Jason P Jan 17 '14 at 18:33
  • I may be wrong, but I see these questions often, and yours looks just like that question, you're trying to set a global variable inside an asynchronous operation, and using that variable in some other function returns `undefined`, because the AJAX request hasn't finished by the time you use the variable, the assignment hasn't yet occurred. – elclanrs Jan 17 '14 at 18:33
  • @elclanrs That may be true, and we can't be certain without more code, but the snippet shows the `console.log()` statement directly following the assignment, both within the `success` callback (if I understand the coffeescript correctly). – Jason P Jan 17 '14 at 18:34
  • This is the line that makes me think that's the issue -- "I later pick up the global variable with window[id] in another function..." – elclanrs Jan 17 '14 at 18:35
  • Does the `console.log(window[id])` statement you show above fail? Maybe there is a namespace issue. Create a different global object and append to that instead of flooding window. – epascarello Jan 17 '14 at 18:35
  • It would help to see more code I guess, where else are you using `window[id]`? – elclanrs Jan 17 '14 at 18:36
  • @elclanrs I'm using `window[id]` later in an `.on 'click'` event, where the user submits something much later (> 30s) when clicking a button. I've removed that line since it's confusing to the question. – Tyler Jan 17 '14 at 18:38
  • 2
    I think there's some context we're missing... can you create a jsfiddle that demonstrates the problem? – Jason P Jan 17 '14 at 18:39
  • That line might be important here. How do you know is 30s? Have you measured the AJAX response time? – elclanrs Jan 17 '14 at 18:40
  • As a quick test, try setting `async:false` in your `$.ajax` options and see if it works. – elclanrs Jan 17 '14 at 18:43
  • OK, added a jsfiddle that replicates the problem: works in Chrome but not in Firefox: http://jsfiddle.net/8Wk9J/ – Tyler Jan 17 '14 at 19:14
  • Well, technically variables can't start with a number, keys of an object can, but `window` must be special. If you create a valid variable name it'll work. ie: http://jsfiddle.net/8Wk9J/1/. Conclusion, don't use `window`, use your own object. – elclanrs Jan 17 '14 at 19:21
  • @elclanrs thanks, that does solve the problem! Oh the vagaries of cross-platform compatibility. Feel free to write up an answer and I'll mark it. – Tyler Jan 17 '14 at 19:25

1 Answers1

1

Technically variables can't start with a number, keys of an object can, but window must be a special case. If you create a valid variable name it'll work. ie: http://jsfiddle.net/8Wk9J/1. Conclusion, don't use window, use your own object:

id = 12345
myobj = {}

$.ajax
  ...
  success: (res, status, xhr) ->
    myobj[id] = ...
    console.log myobj[id] # it should work fine

Also, assigning variables like that inside an asynchronous operation is a source of problems. You never know when that variable is going to be set, and you might get undefined. To avoid future issues I would recommend that you do the logic that depends on the response inside the callback, or you can use the Deffered Object.

elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • Thanks, I'm using my own object now as you suggested, works great. I'm not sure what you mean by the 'response inside the callback' though. My definitions are all inside the callback and based on the response that initiates the callback, so what would I change? – Tyler Jan 17 '14 at 19:42
  • I mean your event that uses the variable. I'm not sure how the rest of your code looks like, but as general rule, every other part of your code that uses that variable should wait for the response to finish, with either the callback, or a promise. – elclanrs Jan 17 '14 at 19:57
  • Window is a special case because it's a readonly arraylike, so assigning to properties that look like array indices is supposed to be ignored per spec. So using `id = "12345a"` would work, but `id = 12345` doesn't. – Boris Zbarsky Jan 17 '14 at 20:48