Skip to content

Commit a45c269

Browse files
authored
Merge pull request #11 from github/not-ok
Handle not successful responses
2 parents 4ee7c3a + 14e86c0 commit a45c269

File tree

4 files changed

+80
-28
lines changed

4 files changed

+80
-28
lines changed

README.md

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,12 @@ remote-input[loading] .loading-icon { display: inline; }
4545

4646
### Events
4747

48-
```js
49-
const remoteInput = document.querySelector('remote-input')
50-
51-
// Network request lifecycle events.
52-
remoteInput.addEventListener('loadstart', function(event) {
53-
console.log('Network request started', event)
54-
})
55-
remoteInput.addEventListener('loadend', function(event) {
56-
console.log('Network request complete', event)
57-
})
58-
remoteInput.addEventListener('load', function(event) {
59-
console.log('Network request succeeded', event)
60-
})
61-
remoteInput.addEventListener('error', function(event) {
62-
console.log('Network request failed', event)
63-
})
64-
```
48+
- `loadstart` - The server fetch has started.
49+
- `load` - The network request completed successfully.
50+
- `error` - The network request failed.
51+
- `loadend` - The network request has completed.
52+
- `remote-input-success` – Received a successful response (status code 200-299). Bubbles.
53+
- `remote-input-error` – Received a not successful response. Bubbles.
6554

6655
## Browser support
6756

index.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,30 @@ async function fetchResults(remoteInput: RemoteInputElement, checkCurrentQuery:
7070

7171
remoteInput.dispatchEvent(new CustomEvent('loadstart'))
7272
remoteInput.setAttribute('loading', '')
73+
let response
74+
let errored = false
75+
let html = ''
7376
try {
74-
const response = await fetch(url, {
77+
response = await fetch(url, {
7578
credentials: 'same-origin',
7679
headers: {accept: 'text/html; fragment'}
7780
})
78-
const html = await response.text()
81+
html = await response.text()
7982
remoteInput.dispatchEvent(new CustomEvent('load'))
80-
resultsContainer.innerHTML = html
8183
} catch {
84+
errored = true
8285
remoteInput.dispatchEvent(new CustomEvent('error'))
8386
}
8487
remoteInput.removeAttribute('loading')
88+
if (errored) return
89+
90+
if (response && response.ok) {
91+
remoteInput.dispatchEvent(new CustomEvent('remote-input-success', {bubbles: true}))
92+
resultsContainer.innerHTML = html
93+
} else {
94+
remoteInput.dispatchEvent(new CustomEvent('remote-input-error', {bubbles: true}))
95+
}
96+
8597
remoteInput.dispatchEvent(new CustomEvent('loadend'))
8698
}
8799

test/karma.config.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
function reply(request, response, next) {
22
if (request.method === 'GET') {
3-
response.writeHead(200)
4-
response.end(`
5-
<ol data-src="${request.url}">
6-
<li>item</li>
7-
<li>item</li>
8-
<li>item</li>
9-
</ol>
10-
`)
3+
if (request.url.startsWith('/500')) {
4+
response.writeHead(500)
5+
response.ok = false
6+
response.end('Server error')
7+
} else if (request.url.startsWith('/network-error')) {
8+
request.destroy(new Error())
9+
response.end()
10+
} else {
11+
response.writeHead(200)
12+
response.ok = true
13+
response.end(`
14+
<ol data-src="${request.url}">
15+
<li>item</li>
16+
<li>item</li>
17+
<li>item</li>
18+
</ol>
19+
`)
20+
}
1121
return
1222
}
1323
next()

test/test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,55 @@ describe('remote-input', function() {
3030
const input = document.querySelector('input')
3131
const results = document.querySelector('#results')
3232
assert.equal(results.innerHTML, '')
33+
let successEvent = false
34+
remoteInput.addEventListener('remote-input-success', function() {
35+
successEvent = true
36+
})
3337
remoteInput.addEventListener('loadend', function() {
38+
assert.ok(successEvent, 'success event happened')
3439
assert.equal(results.querySelector('ol').getAttribute('data-src'), '/results?q=test')
3540
done()
3641
})
3742
input.value = 'test'
3843
input.focus()
3944
})
4045

46+
it('handles not ok responses', function(done) {
47+
const remoteInput = document.querySelector('remote-input')
48+
const input = document.querySelector('input')
49+
const results = document.querySelector('#results')
50+
remoteInput.src = '/500'
51+
assert.equal(results.innerHTML, '')
52+
let errorEvent = false
53+
remoteInput.addEventListener('remote-input-error', function() {
54+
errorEvent = true
55+
})
56+
remoteInput.addEventListener('loadend', function() {
57+
assert.ok(errorEvent, 'error event happened')
58+
assert.equal(results.innerHTML, '', 'nothing was appended')
59+
done()
60+
})
61+
input.value = 'test'
62+
input.focus()
63+
})
64+
65+
it('handles network error', function(done) {
66+
const remoteInput = document.querySelector('remote-input')
67+
const input = document.querySelector('input')
68+
const results = document.querySelector('#results')
69+
remoteInput.src = '/network-error'
70+
assert.equal(results.innerHTML, '')
71+
remoteInput.addEventListener('error', async function() {
72+
await Promise.resolve()
73+
assert.equal(results.innerHTML, '', 'nothing was appended')
74+
assert.notOk(remoteInput.hasAttribute('loading'), 'loading attribute was removed')
75+
done()
76+
})
77+
input.value = 'test'
78+
input.focus()
79+
assert.ok(remoteInput.hasAttribute('loading'), 'loading attribute was added')
80+
})
81+
4182
it('repects param attribute', function(done) {
4283
const remoteInput = document.querySelector('remote-input')
4384
const input = document.querySelector('input')

0 commit comments

Comments
 (0)