Skip to content

Commit

Permalink
fix resource invoke context
Browse files Browse the repository at this point in the history
  • Loading branch information
Varixo committed Jan 7, 2025
1 parent 984011a commit a6492f8
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/qwik/src/core/signal/signal-subscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ function clearStoreEffects(storeHandler: StoreHandler, value: Subscriber | VNode
subscriptionRemoved = true;
}
}
if (effects.length === 0) {
delete effectSubscriptions[key];
}
}

return subscriptionRemoved;
Expand Down
110 changes: 110 additions & 0 deletions packages/qwik/src/core/tests/use-resource.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
component$,
useResource$,
useSignal,
useStore,
type ResourceReturn,
} from '@qwik.dev/core';
import { domRender, getTestPlatform, ssrRenderToDom, trigger } from '@qwik.dev/core/testing';
import { describe, expect, it } from 'vitest';
Expand All @@ -16,6 +18,10 @@ import '../../testing/vdom-diff.unit-util';
const debug = false; //true;
Error.stackTraceLimit = 100;

export function mutable(value: any) {
return value;
}

describe.each([
{ render: ssrRenderToDom }, //
{ render: domRender }, //
Expand Down Expand Up @@ -409,4 +415,108 @@ describe.each([
</Component>
);
});

it('should track subscription', async () => {
const Results = component$((props: { result: ResourceReturn<number> }) => {
const state = useStore({
count: 0,
});
return (
<div>
<Resource
value={props.result}
onResolved={(number) => {
return (
<>
<div>resource 1 is {number}</div>
<button onClick$={() => state.count++}>
count is {mutable(state.count + 0)}
</button>
</>
);
}}
/>
</div>
);
});

const ResourceApp = component$(() => {
const resource = useResource$<number>(() => {
return 0;
});

return <Results result={resource} />;
});

const { vNode, document } = await render(<ResourceApp />, { debug });
expect(vNode).toMatchVDOM(
<Component>
<Component>
<div>
<InlineComponent>
<Fragment>
<Awaited>
<Fragment>
<div>
{'resource 1 is '}
{'0'}
</div>
<button>{'count is '}0</button>
</Fragment>
</Awaited>
</Fragment>
</InlineComponent>
</div>
</Component>
</Component>
);

await trigger(document.body, 'button', 'click');

expect(vNode).toMatchVDOM(
<Component>
<Component>
<div>
<InlineComponent>
<Fragment>
<Awaited>
<Fragment>
<div>
{'resource 1 is '}
{'0'}
</div>
<button>{'count is '}1</button>
</Fragment>
</Awaited>
</Fragment>
</InlineComponent>
</div>
</Component>
</Component>
);

await trigger(document.body, 'button', 'click');

expect(vNode).toMatchVDOM(
<Component>
<Component>
<div>
<InlineComponent>
<Fragment>
<Awaited>
<Fragment>
<div>
{'resource 1 is '}
{'0'}
</div>
<button>{'count is '}2</button>
</Fragment>
</Awaited>
</Fragment>
</InlineComponent>
</div>
</Component>
</Component>
);
});
});
6 changes: 3 additions & 3 deletions packages/qwik/src/core/use/use-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,14 @@ function getResourceValueAsPromise<T>(props: ResourceProps<T>): Promise<JSXOutpu
DEBUG && debugLog(`RESOURCE_CMP.${state}`, 'VALUE: ' + untrack(() => resource._resolved));

if (state === 'pending' && props.onPending) {
return Promise.resolve(props.onPending());
return Promise.resolve().then(useBindInvokeContext(props.onPending));
} else if (state === 'rejected' && props.onRejected) {
return Promise.resolve(resource._error!).then(props.onRejected);
return Promise.resolve(resource._error!).then(useBindInvokeContext(props.onRejected));
} else {
const resolvedValue = untrack(() => resource._resolved) as T;
if (resolvedValue !== undefined) {
// resolved, pending without onPending prop or rejected without onRejected prop
return Promise.resolve(resolvedValue).then(props.onResolved);
return Promise.resolve(resolvedValue).then(useBindInvokeContext(props.onResolved));
}
}
}
Expand Down

0 comments on commit a6492f8

Please sign in to comment.