Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/brown-ways-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack-query-firebase/angular": patch
---

Fix issue where signal updates weren't getting picked up
2 changes: 1 addition & 1 deletion dataconnect-sdk/js/default-connector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
"./package.json": "./package.json"
},
"peerDependencies": {
"firebase": "^10.14.0 || ^11.3.0"
"firebase": "^10.14.0 || ^11.3.0 || ^12.0.0"
}
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
"build": "turbo build"
},
"devDependencies": {
"@angular/core": "^19.1.8",
"@angular/core": "^20.0.0",
"@biomejs/biome": "2.1.1",
"@changesets/cli": "^2.29.4",
"@tanstack/angular-query-experimental": "5.66.4",
"@tanstack/angular-query-experimental": "^5.66.4",
"@tanstack/react-query": "^5.55.4",
"@types/jsonwebtoken": "^9.0.7",
"@vitest/coverage-istanbul": "^2.0.5",
Expand All @@ -33,6 +33,6 @@
"vitest": "^2.0.5"
},
"dependencies": {
"@angular/fire": "^19.0.0"
"@angular/fire": "^20.0.0"
}
}
14 changes: 6 additions & 8 deletions packages/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,15 @@
"license": "Apache-2.0",
"devDependencies": {
"@dataconnect/default-connector": "file:../../dataconnect-sdk/js/default-connector",
"@analogjs/vite-plugin-angular": "^1.13.0",
"@angular/animations": "^19.0.0",
"@testing-library/angular": "^17.3.5",
"@testing-library/angular": "^18.0.0",
"@testing-library/dom": "^10.4.0",
"tsup": "^8.4.0"
},
"peerDependencies": {
"@tanstack/angular-query-experimental": "5.66.4",
"@angular/core": "^19.0.0",
"@angular/fire": "^19.0.0",
"@angular/common": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0"
"@angular/common": "^20.0.0 || ^19.0.0",
"@angular/core": "^20.0.0 || ^19.0.0",
"@angular/fire": "^20.0.0 || ^19.0.0",
"@angular/platform-browser-dynamic": "^20.0.0 || ^19.0.0",
"@tanstack/angular-query-experimental": "^5.66.4"
}
}
56 changes: 30 additions & 26 deletions packages/angular/src/data-connect/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
computed,
EnvironmentInjector,
type Injector,
inject,
Expand Down Expand Up @@ -60,36 +61,39 @@ export function injectDataConnectQuery<Data, Variables>(
Partial<QueryResult<Data, Variables>> | undefined
>(undefined);
const finalInjector = injector || inject(EnvironmentInjector);
const queryKey = signal<QueryKey>([]);
const varsSignal = computed(() =>
typeof queryRefOrOptionsFn === "function"
? queryRefOrOptionsFn().queryFn().variables
: queryRefOrOptionsFn.variables,
);
const queryRefSignal = computed(() =>
typeof queryRefOrOptionsFn === "function"
? queryRefOrOptionsFn().queryFn()
: queryRefOrOptionsFn,
);
const optionsSignal = computed(() =>
typeof queryRefOrOptionsFn === "function"
? queryRefOrOptionsFn()
: undefined,
);

function fdcOptionsFn() {
const passedInOptions =
typeof queryRefOrOptionsFn === "function"
? queryRefOrOptionsFn()
: undefined;

const modifiedFn = async (): Promise<Data> => {
const ref: QueryRef<Data, Variables> =
passedInOptions?.queryFn() ||
(queryRefOrOptionsFn as QueryRef<Data, Variables>);
dataConnectResult.set({ ref });
// @ts-expect-error function is hidden under `DataConnect`.
ref.dataConnect._setCallerSdkType(_callerSdkType);
queryKey.set([ref.name, ref.variables]);
const response = await executeQuery(ref);
dataConnectResult.set(response);
return response.data;
};
async function queryFn() {
const queryRef = queryRefSignal();
// @ts-expect-error function is hidden under `DataConnect`.
queryRef.dataConnect._setCallerSdkType(_callerSdkType);
const response = await executeQuery(queryRef);
dataConnectResult.set(response);
return response.data;
}
const injectQueryResult = injectQuery(() => {
return {
queryKey: queryKey(),
...passedInOptions,
queryFn: modifiedFn,
queryKey: [queryRefSignal().name, varsSignal()],
...optionsSignal(),
queryFn: queryFn,
};
}

const originalResult = injectQuery(fdcOptionsFn, finalInjector);
}, finalInjector);
return {
...originalResult,
...injectQueryResult,
dataConnectResult,
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { provideHttpClient } from "@angular/common/http";
import { provideExperimentalZonelessChangeDetection } from "@angular/core";
import { provideZonelessChangeDetection } from "@angular/core";
import { TestBed } from "@angular/core/testing";
import { initializeApp, provideFirebaseApp } from "@angular/fire/app";
import {
Expand Down Expand Up @@ -44,7 +44,7 @@ describe("injectDataConnectMutation", () => {
invalidateQueriesSpy = vi.spyOn(queryClient, "invalidateQueries");
TestBed.configureTestingModule({
providers: [
provideExperimentalZonelessChangeDetection(), // Required as angularfire's ZoneScheduler breaks tests.
provideZonelessChangeDetection(), // Required as angularfire's ZoneScheduler breaks tests.
provideFirebaseApp(() => initializeApp({ projectId: "p" })),
provideDataConnect(() => {
const dc = getDataConnect(connectorConfig);
Expand Down
39 changes: 34 additions & 5 deletions packages/angular/src/data-connect/injectDataConnectQuery.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { provideHttpClient } from "@angular/common/http";
import {
inject,
provideExperimentalZonelessChangeDetection,
} from "@angular/core";
import { inject, provideZonelessChangeDetection, signal } from "@angular/core";
import { TestBed } from "@angular/core/testing";
import { initializeApp, provideFirebaseApp } from "@angular/fire/app";
import {
Expand Down Expand Up @@ -35,7 +32,7 @@ describe("injectDataConnectQuery", () => {
queryClient.clear();
TestBed.configureTestingModule({
providers: [
provideExperimentalZonelessChangeDetection(), // Required as angularfire's ZoneScheduler breaks tests.
provideZonelessChangeDetection(), // Required as angularfire's ZoneScheduler breaks tests.
provideFirebaseApp(() => initializeApp({ projectId: "p" })),
provideDataConnect(() => {
const dc = getDataConnect(connectorConfig);
Expand Down Expand Up @@ -243,4 +240,36 @@ describe("injectDataConnectQuery", () => {
// // })
// expect(r).toBeDefined();
});
test("signal updates are received", async () => {
const movieData = {
title: "tanstack query firebase",
genre: "library",
imageUrl: "https://invertase.io/",
};
const createdMovie = await createMovie(movieData);

const movieId = createdMovie?.data?.movie_insert?.id;
const movieIdSignal = signal("");

const result = TestBed.runInInjectionContext(() =>
injectDataConnectQuery(() => ({
queryFn: () => getMovieByIdRef({ id: movieIdSignal() }),
retry: false,
})),
);

expect(result.isPending()).toBe(true);

await waitFor(() => expect(result.isPending()).toBe(false));
expect(result.isSuccess()).to.be.false;
expect(result.data()).toBeUndefined();
expect(result.error()).toBeDefined();

movieIdSignal.set(movieId);
await waitFor(() => expect(result.isSuccess()).toBe(true));
expect(result.data()!.movie).to.deep.equal({
id: movieId,
...movieData,
});
});
});
Loading