Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#15884 closed defect (fixed)

Deferred resolved twice when using Dojox.Layout.ContentPane

Reported by: pauldailly Owned by: bill
Priority: undecided Milestone: 1.8.1
Component: DojoX Layout Version: 1.8.0
Keywords: Cc: pauldaillycc@…
Blocked By: Blocking:

Description

Browser Type: Non browser specific OS: Tested on Windows XP/MAC OS X Lion Email: pauldaillycc@…

I have recently upgraded from Dojo 1.7.3 to 1.8. Since doing so I have experienced an issue when using Dojox.Layout.ContentPane?. I have an instance of the ContentPane? which retrieves an HTML fragment using the set('href',...) method. Since moving to 1.8 I now receive the following error when trying to retrieve content using set('href',...):

"Error undefined running custom onLoad code: This deferred has already been resolved"

Having done some initial investigation it appears that the Deferred in Digit.Layout.ContentPane? called 'onLoadDeferred' is being resolved twice. This is due to the _onLoadHandler() method of Digit.Layout.ContentPane? being called twice. It appears that the _onLoadHandler() method gets called once prior to the set('href'...) method being called and once as a result of the set('href',...) call.

I have compared this to the behaviour in 1.7.3 and whilst _onLoadHandler() is still called twice, there is no error. The only difference I can see between 1.7.3 and 1.8 is that in 1.7.3 the _onLoadHandler() method uses this.onLoadDeferred.callback(data) whereas in 1.8 it uses this.onLoadDeferred.resolve(data).

I am fairly new to Dojo so I am not sure what is causing this error seen in 1.8. It is worth noting that using the Digit.Layout.ContentPane? directly in 1.8 does not result in this error occuring.

This is the first issue I have reported here so apologies if it does not contain the relevant details. Please let me know if there is any further information I can provide to help clarify the issue.

Thanks,

Paul

Attachments (2)

contentpane.html (911 bytes) - added by pauldailly 7 years ago.
Creates a content pane and makes Ajax call to load HTML fragment
pagecontent.html (98 bytes) - added by pauldailly 7 years ago.
The HTML fragment requested by contentpane.html

Download all attachments as: .zip

Change History (8)

comment:1 Changed 7 years ago by bill

Cc: pauldaillycc@… added

Hi Paul, that's a good description but can you attach a test case that reproduces the problem?

Please attach a test case using the "attach file" button. It should be as small as possible to still reproduce the problem, almost always a single HTML file that we can load in the browser and use to reproduce then problem.

Then, give exact instructions on how to reproduce the problem using your attached test file.

The test case is necessary both to confirm that there's a bug, and for us to be able to debug the problem.

Thanks!

Changed 7 years ago by pauldailly

Attachment: contentpane.html added

Creates a content pane and makes Ajax call to load HTML fragment

Changed 7 years ago by pauldailly

Attachment: pagecontent.html added

The HTML fragment requested by contentpane.html

comment:2 in reply to:  1 Changed 7 years ago by pauldailly

Replying to bill:

Hi Paul, that's a good description but can you attach a test case that reproduces the problem?

Please attach a test case using the "attach file" button. It should be as small as possible to still reproduce the problem, almost always a single HTML file that we can load in the browser and use to reproduce then problem.

Then, give exact instructions on how to reproduce the problem using your attached test file.

The test case is necessary both to confirm that there's a bug, and for us to be able to debug the problem.

Thanks!

Hi Bill, thanks for getting back to me. I have attached 2 files which hopefully clarify the issue I am experiencing. The first file 'contentpane.html' creates a dojox.Layout.ContentPane? and calls set('href', ...) to pull in the contents of 'pagecontent.html'. Please let me know if you need any further information.

Thanks,

Paul

Last edited 7 years ago by pauldailly (previous) (diff)

comment:3 Changed 7 years ago by bill

Milestone: tbd1.8.1
Owner: set to bill
Status: newassigned

Thanks for the test case and analysis. It's actually not happening on trunk, due to [29511], but that may be random. I'll take a look.

comment:4 Changed 7 years ago by bill

Notes on this bug:

During initialization, when _WidgetBase applies the attributes (ie, calls custom setters for each attribute), _WidgetBase calls _setContentAttr(empty-document-fragment). _WidgetBase expects that call to be synchronous, but it isn't. _setContentAttr() calls _setContent(), and that calls setter.set(), that calls dojox/html/_base.js::onEnd(), and that calls ready(), to wait for any possible <script>require(...)</script> type blocks (in the ContentPane content) to complete running.

So, while ready() is "blocking", _WidgetBase continues applying attributes, and calls_setHrefAttr(). _setHrefAttr() creates the onLoadDeferred to signal when the href has finished downloading and parser. Then while that href download is running, ready() stops blocking, so it calls _onLoadHandler, and resolves the onLoadDeferred created by _setHrefAttr().

In other words, _setContentAttr() and _setHrefAttr() unexpectedly overlap each other, and the problem is made worse because there's a instance-level onLoadDeferred property that gets confused between them.

PS: the content is actually set three times, once to the original content (the empty DocumentFragment), once to "Loading..." (but in this case the isFakeContent flag is set), and finally to the content of the href.

Version 1, edited 7 years ago by bill (previous) (next) (diff)

comment:5 Changed 7 years ago by bill

Resolution: fixed
Status: assignedclosed

In [29543]:

Don't call ready() unnecessarily; it can make the internal set("content", ...) call during initialization asynchronous, which breaks the widget creation lifecycle when an href is specified. Fixes #15884 on 1.8 branch !strict.

comment:6 Changed 7 years ago by bill

In [29544]:

Don't call ready() unnecessarily; it can make the internal set("content", ...) call during initialization asynchronous, which breaks the widget creation lifecycle when an href is specified. Fixes #15884 on trunk !strict.

Note: See TracTickets for help on using tickets.