diff --git a/src/client/dapi/DataApiMediator.js b/src/client/dapi/DataApiMediator.js index bdca195..89b600b 100644 --- a/src/client/dapi/DataApiMediator.js +++ b/src/client/dapi/DataApiMediator.js @@ -177,7 +177,11 @@ module.exports = Class( 'DataApiMediator', update[ name ] = field_update; - quote.setData( update ); + // allow the stack to clear before setting data to allow any + // existing bucket processing to complete before hooks are kicked + // off yet again (which, in practice, could otherwise result in + // infinite recursion depending on what the hooks are doing) + setTimeout( () => quote.setData( update ) ); }, diff --git a/test/client/dapi/DataApiMediatorTest.js b/test/client/dapi/DataApiMediatorTest.js index fee5f56..62e12b1 100644 --- a/test/client/dapi/DataApiMediatorTest.js +++ b/test/client/dapi/DataApiMediatorTest.js @@ -319,7 +319,8 @@ describe( "DataApiMediator", () => { it( label, done => { - let set_options = false; + let set_options = false; + let stack_cleared = false; const quote = { getDataByName( given_name ) @@ -329,6 +330,9 @@ describe( "DataApiMediator", () => setData( given_data ) { + // we should have allowed the stack to clear first + expect( stack_cleared ).to.be.true; + expect( given_data ).to.deep.equal( expected ); // should have called setOptions by now @@ -382,6 +386,11 @@ describe( "DataApiMediator", () => dapi_manager.emit( 'updateFieldData', name, index, val_label, results ); + + // #setData should be triggered after the stack clears to + // #mitigate issues with hooks causing too much / infinite + // #recursion on the bucket on the same stack + stack_cleared = true; } ); } );