diff --git a/aio/content/guide/service-worker-notifications.md b/aio/content/guide/service-worker-notifications.md index 44d683400e955..fa354a2ed6c97 100644 --- a/aio/content/guide/service-worker-notifications.md +++ b/aio/content/guide/service-worker-notifications.md @@ -61,11 +61,12 @@ The Angular service worker supports the following operations: | `openWindow` | Opens a new tab at the specified URL, which is resolved relative to the service worker scope. | | `focusLastFocusedOrOpen` | Focuses the last focused client. If there is no client open, then it opens a new tab at the specified URL, which is resolved relative to the service worker scope. | | `navigateLastFocusedOrOpen` | Focuses the last focused client and navigates it to the specified URL, which is resolved relative to the service worker scope. If there is no client open, then it opens a new tab at the specified URL. | +| `sendRequest` | Send a simple GET request to the specified URL. |
If an `onActionClick` item does not define a `url`, then the service worker's registration scope is used. - +
### Actions @@ -86,14 +87,16 @@ In addition, using the `onActionClick` property on the `data` object, you can ti {"action": "foo", "title": "Open new tab"}, {"action": "bar", "title": "Focus last"}, {"action": "baz", "title": "Navigate last"}, - {"action": "qux", "title": "Just notify existing clients"} + {"action": "qux", "title": "Send request in the background"} + {"action": "other", "title": "Just notify existing clients"} ], "data": { "onActionClick": { "default": {"operation": "openWindow"}, "foo": {"operation": "openWindow", "url": "/absolute/path"}, "bar": {"operation": "focusLastFocusedOrOpen", "url": "relative/path"}, - "baz": {"operation": "navigateLastFocusedOrOpen", "url": "https://other.domain.com/"} + "baz": {"operation": "navigateLastFocusedOrOpen", "url": "https://other.domain.com/"}, + "qux": {"operation": "sendRequest", "url": "https://yet.another.domain.com/"} } } } diff --git a/packages/service-worker/worker/src/driver.ts b/packages/service-worker/worker/src/driver.ts index 9c0fc8b05f823..1862b0fe129b2 100644 --- a/packages/service-worker/worker/src/driver.ts +++ b/packages/service-worker/worker/src/driver.ts @@ -380,6 +380,10 @@ export class Driver implements Debuggable, UpdateSource { } break; } + case 'sendRequest': { + await this.scope.fetch(urlToOpen); + break; + } default: break; } diff --git a/packages/service-worker/worker/test/happy_spec.ts b/packages/service-worker/worker/test/happy_spec.ts index 5b478eb3f0a84..9308e38a2e2e8 100644 --- a/packages/service-worker/worker/test/happy_spec.ts +++ b/packages/service-worker/worker/test/happy_spec.ts @@ -1035,6 +1035,55 @@ describe('Driver', () => { }); }); + describe('`sendRequest` operation', () => { + it('sends a GET request to the specified URL', async () => { + // Initialize the SW. + expect(await makeRequest(scope, '/foo.txt')).toBe('this is foo'); + await driver.initialized; + server.clearRequests(); + + // Trigger a `notificationlick` event. + const url = '/some/url'; + await scope.handleClick( + { + title: 'Test notification', + body: 'This is a test notifiction.', + data: { + onActionClick: { + foo: {operation: 'sendRequest', url}, + }, + }, + }, + 'foo'); + + // Expect request to the server. + server.assertSawRequestFor('/some/url'); + }); + + it('falls back to sending a request to `/` when no URL is specified', async () => { + // Initialize the SW. + expect(await makeRequest(scope, '/foo.txt')).toBe('this is foo'); + await driver.initialized; + server.clearRequests(); + + // Trigger a `notificationlick` event. + await scope.handleClick( + { + title: 'Test notification', + body: 'This is a test notifiction.', + data: { + onActionClick: { + bar: {operation: 'sendRequest'}, + }, + }, + }, + 'bar'); + + // Expect request to the server. + server.assertSawRequestFor('/'); + }); + }); + describe('No matching onActionClick field', () => { it('no client interaction', async () => { expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');