Skip to content

Commit 3830908

Browse files
angelakiAndrewKushnir
authored andcommitted
feat(service-worker): support sendRequest as a notificationclick action (#46912)
Implement a new `notificationclick` action, `sendRequest`, which sends a GET request to the specified URL, without opening a new window. This can be useful for hitting an API endpoint. PR Close #46912
1 parent 49e1912 commit 3830908

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

aio/content/guide/service-worker-notifications.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,12 @@ The Angular service worker supports the following operations:
6161
| `openWindow` | Opens a new tab at the specified URL, which is resolved relative to the service worker scope. |
6262
| `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. |
6363
| `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. |
64+
| `sendRequest` | Send a simple GET request to the specified URL. |
6465

6566
<div class="alert is-important">
6667

6768
If an `onActionClick` item does not define a `url`, then the service worker's registration scope is used.
68-
69+
6970
</div>
7071

7172
### Actions
@@ -86,14 +87,16 @@ In addition, using the `onActionClick` property on the `data` object, you can ti
8687
{"action": "foo", "title": "Open new tab"},
8788
{"action": "bar", "title": "Focus last"},
8889
{"action": "baz", "title": "Navigate last"},
89-
{"action": "qux", "title": "Just notify existing clients"}
90+
{"action": "qux", "title": "Send request in the background"}
91+
{"action": "other", "title": "Just notify existing clients"}
9092
],
9193
"data": {
9294
"onActionClick": {
9395
"default": {"operation": "openWindow"},
9496
"foo": {"operation": "openWindow", "url": "/absolute/path"},
9597
"bar": {"operation": "focusLastFocusedOrOpen", "url": "relative/path"},
96-
"baz": {"operation": "navigateLastFocusedOrOpen", "url": "https://other.domain.com/"}
98+
"baz": {"operation": "navigateLastFocusedOrOpen", "url": "https://other.domain.com/"},
99+
"qux": {"operation": "sendRequest", "url": "https://yet.another.domain.com/"}
97100
}
98101
}
99102
}

packages/service-worker/worker/src/driver.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ export class Driver implements Debuggable, UpdateSource {
380380
}
381381
break;
382382
}
383+
case 'sendRequest': {
384+
await this.scope.fetch(urlToOpen);
385+
break;
386+
}
383387
default:
384388
break;
385389
}

packages/service-worker/worker/test/happy_spec.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,55 @@ describe('Driver', () => {
10351035
});
10361036
});
10371037

1038+
describe('`sendRequest` operation', () => {
1039+
it('sends a GET request to the specified URL', async () => {
1040+
// Initialize the SW.
1041+
expect(await makeRequest(scope, '/foo.txt')).toBe('this is foo');
1042+
await driver.initialized;
1043+
server.clearRequests();
1044+
1045+
// Trigger a `notificationlick` event.
1046+
const url = '/some/url';
1047+
await scope.handleClick(
1048+
{
1049+
title: 'Test notification',
1050+
body: 'This is a test notifiction.',
1051+
data: {
1052+
onActionClick: {
1053+
foo: {operation: 'sendRequest', url},
1054+
},
1055+
},
1056+
},
1057+
'foo');
1058+
1059+
// Expect request to the server.
1060+
server.assertSawRequestFor('/some/url');
1061+
});
1062+
1063+
it('falls back to sending a request to `/` when no URL is specified', async () => {
1064+
// Initialize the SW.
1065+
expect(await makeRequest(scope, '/foo.txt')).toBe('this is foo');
1066+
await driver.initialized;
1067+
server.clearRequests();
1068+
1069+
// Trigger a `notificationlick` event.
1070+
await scope.handleClick(
1071+
{
1072+
title: 'Test notification',
1073+
body: 'This is a test notifiction.',
1074+
data: {
1075+
onActionClick: {
1076+
bar: {operation: 'sendRequest'},
1077+
},
1078+
},
1079+
},
1080+
'bar');
1081+
1082+
// Expect request to the server.
1083+
server.assertSawRequestFor('/');
1084+
});
1085+
});
1086+
10381087
describe('No matching onActionClick field', () => {
10391088
it('no client interaction', async () => {
10401089
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');

0 commit comments

Comments
 (0)