Skip to content

Commit

Permalink
Merge pull request #471 from meteor/async-with
Browse files Browse the repository at this point in the history
Added support for `Promise`s in `#with` (closes #469).
  • Loading branch information
jankapunkt authored Oct 28, 2024
2 parents 0856ca8 + c743df6 commit 7d1b144
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 19 deletions.
16 changes: 4 additions & 12 deletions packages/blaze/builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,9 @@ Blaze._calculateCondition = function (cond) {
Blaze.With = function (data, contentFunc) {
const view = Blaze.View('with', contentFunc);

view.dataVar = new ReactiveVar();

view.onViewCreated(function () {
if (typeof data === 'function') {
// `data` is a reactive function
view.autorun(function () {
view.dataVar.set(data());
}, view.parentView, 'setData');
} else {
view.dataVar.set(data);
}
view.dataVar = null;
view.onViewCreated(() => {
view.dataVar = _createBinding(view, data, 'setData');
});

return view;
Expand Down Expand Up @@ -313,7 +305,7 @@ Blaze.Each = function (argFunc, contentFunc, elseFunc) {
if (eachView.variableName) {
itemView._scopeBindings[eachView.variableName].set({ value: newItem });
} else {
itemView.dataVar.set(newItem);
itemView.dataVar.set({ value: newItem });
}
}
});
Expand Down
4 changes: 2 additions & 2 deletions packages/blaze/lookup.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ Blaze._parentData = function (height, _functionWrapped) {
if (! theWith)
return null;
if (_functionWrapped)
return function () { return theWith.dataVar.get(); };
return theWith.dataVar.get();
return function () { return theWith.dataVar.get()?.value; };
return theWith.dataVar.get()?.value;
};


Expand Down
2 changes: 1 addition & 1 deletion packages/blaze/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ Blaze.getData = function (elementOrView) {
throw new Error("Expected DOM element or View");
}

return theWith ? theWith.dataVar.get() : null;
return theWith ? theWith.dataVar.get()?.value : null;
};

// For back-compat
Expand Down
4 changes: 4 additions & 0 deletions packages/spacebars-tests/async_tests.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,7 @@
<template name="spacebars_async_tests_each_new">
{{#each y in x}}{{y}}{{else}}0{{/each}}
</template>

<template name="spacebars_async_tests_with">
{{#with x}}{{y}}{{/with}}
</template>
16 changes: 13 additions & 3 deletions packages/spacebars-tests/async_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ function asyncTest(templateName, testName, fn) {
}

function asyncSuite(templateName, cases) {
for (const [testName, helpers, before, after] of cases) {
for (const [testName, helpers, before, after, cycles = 1] of cases) {
asyncTest(templateName, testName, async (test, template, render) => {
template.helpers(helpers);
const readHTML = render();
test.equal(readHTML(), before);
await new Promise(Tracker.afterFlush);
// Some test cases require more cycles to propagate.
for (let cycle = 0; cycle < cycles; ++cycle) {
test.equal(readHTML(), before);
await new Promise(Tracker.afterFlush);
}
test.equal(readHTML(), after);
});
}
Expand Down Expand Up @@ -117,6 +120,13 @@ asyncSuite('each_new', [
['two', { x: Promise.resolve([1, 2]) }, '0', '12'],
]);

asyncSuite('with', [
['null', { x: Promise.resolve(null) }, '', '', 2],
['empty', { x: Promise.resolve({}) }, '', '', 2],
['direct', { x: Promise.resolve({y: 1}) }, '', '1', 2],
['wrapped', { x: Promise.resolve({y: Promise.resolve(1)}) }, '', '1', 3],
]);

// In the following tests pending=1, rejected=2, resolved=3.
const pending = new Promise(() => {});
const rejected = Promise.reject();
Expand Down
2 changes: 1 addition & 1 deletion packages/templating-runtime/templating.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Template._applyHmrChanges = function (templateName) {
var newView = Blaze.render(Template.body, document.body, comment);
Template.body.view = newView;
} else if (view.dataVar) {
Blaze.renderWithData(renderFunc, view.dataVar.curValue, parentEl, comment);
Blaze.renderWithData(renderFunc, view.dataVar.curValue?.value, parentEl, comment);
} else {
Blaze.render(renderFunc, parentEl, comment);
}
Expand Down

0 comments on commit 7d1b144

Please sign in to comment.