Skip to content

Commit

Permalink
fix: #332 bindToQueryString is not immediate in vue3
Browse files Browse the repository at this point in the history
  • Loading branch information
ascott18 committed Oct 27, 2023
1 parent 9779f66 commit 70343f5
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 20 deletions.
40 changes: 23 additions & 17 deletions src/coalesce-vue/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,24 @@ export function bindToQueryString(
}
);

const updateObject = (v: any) => {
obj[key] =
// Use the default value if null or undefined
v == null
? defaultValue
: // Use provided parse function, if provided.
parse
? parse(v)
: // Use metadata to parse the value if the obj is a DataSource.
obj?.$metadata?.params?.[key]
? mapToModel(v, obj.$metadata.params[key])
: obj?.$metadata?.props?.[key]
? mapToModel(v, obj.$metadata.props[key])
: // TODO: Add $metadata to DataSourceParameters/FilterParameters/ListParameters, and then support that as well.
// Fallback to the raw value
v;
};

// When the query changes, grab the new value.
vue.$watch(
() => vue.$route?.query[queryKey],
Expand All @@ -1021,24 +1039,12 @@ export function bindToQueryString(
}
}

obj[key] =
// Use the default value if null or undefined
v == null
? defaultValue
: // Use provided parse function, if provided.
parse
? parse(v)
: // Use metadata to parse the value if the obj is a DataSource.
obj?.$metadata?.params?.[key]
? mapToModel(v, obj.$metadata.params[key])
: obj?.$metadata?.props?.[key]
? mapToModel(v, obj.$metadata.props[key])
: // TODO: Add $metadata to DataSourceParameters/FilterParameters/ListParameters, and then support that as well.
// Fallback to the raw value
v;
},
{ immediate: true }
updateObject(v);
}
);

// Fix #332: circumvent the `await nextTick` above on the initial call"
updateObject(vue.$route?.query[queryKey]);
}

export function useBindToQueryString(
Expand Down
57 changes: 54 additions & 3 deletions src/coalesce-vue/vue3-tests/model.spec.vue3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import {
RouterView,
createWebHistory,
RouterLink,
createMemoryHistory,
} from "vue-router";
import { bindToQueryString } from "../src";
import { mount } from "@vue/test-utils";
import { delay } from "../test/test-utils";

describe("bindToQueryString", () => {
test("does not put values on new route when changing routes", async () => {
// TO VALIDATE IF THE UNDERLYING PROBLEM IS STILL A PROBLEM:
// Comment the code in bindToQueryString that checks for `isUnmounted` and does a $nextTick.

let changeBoundValue: Function;
var router = createRouter({
history: createWebHistory(), // Note: memory history doesn't reproduce the bug.
Expand Down Expand Up @@ -85,6 +83,59 @@ describe("bindToQueryString", () => {
}
});

test("sets query value before returning", async () => {
let boundValueNewValue;
var router = createRouter({
history: createMemoryHistory(),
routes: [
{
path: "/",
component: defineComponent({ render: () => h("div") }),
},
{
path: "/two",
component: defineComponent({
data() {
return { boundValue: "" };
},
created() {
bindToQueryString(this, this, "boundValue");
boundValueNewValue = this.boundValue;
},
render: () => h("div"),
}),
},
],
});

const app = mount(
defineComponent({
render() {
return h(RouterView);
},
}),
{
global: { plugins: [router] },
attachTo: document.body,
}
);

try {
// wait for mount
await delay(1);

// Navigate to another page that uses binding
await router.push("/two?boundValue=foo");

// Value from the route should now be in boundValueNewValue.
await delay(1);
expect(boundValueNewValue).toBe("foo");
} finally {
// Cleanup: reset route for other tests
await router.push("/");
}
});

test("handles multiple bound values changing simultaneously", async () => {
let setBoundValues: (v: string | null) => void;
console.log(window.location.href);
Expand Down

0 comments on commit 70343f5

Please sign in to comment.