Skip to content

Commit 0e3b2e3

Browse files
Merge pull request #474 from Codeinwp/feat/onboarding-search-cancel
feat(onboarding): truly cancel superseded starter-site searches
2 parents 96bbd34 + 716946f commit 0e3b2e3

2 files changed

Lines changed: 31 additions & 9 deletions

File tree

onboarding/src/Components/Steps/SiteList.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ import { get, track } from '../../utils/rest';
1717

1818
const { onboarding } = tiobDash;
1919

20+
// Debounce the search so it stays off the network while typing: only fire after the
21+
// field is idle for SEARCH_DEBOUNCE_MS and the query is at least SEARCH_MIN_CHARS.
22+
const SEARCH_DEBOUNCE_MS = 700;
23+
const SEARCH_MIN_CHARS = 3;
24+
2025
// Guards tracking-session init against firing twice while the first request is in flight.
2126
let trackingInitStarted = false;
2227

@@ -89,7 +94,6 @@ const SiteList = ( {
8994
}
9095

9196
let active = true;
92-
let safety;
9397
const reveal = setTimeout( () => {
9498
if ( active ) {
9599
setPersonalizing( true );
@@ -103,7 +107,7 @@ const SiteList = ( {
103107
}
104108
};
105109

106-
safety = setTimeout( done, 9000 );
110+
const safety = setTimeout( done, 9000 );
107111
get(
108112
onboarding.root +
109113
'/starter_order?builder=' +
@@ -134,13 +138,15 @@ const SiteList = ( {
134138
setSearchFailed( false );
135139

136140
const q = ( searchQuery || '' ).trim();
137-
if ( q.length < 3 ) {
141+
if ( q.length < SEARCH_MIN_CHARS ) {
138142
setSearching( false );
139143
return undefined;
140144
}
141145

142146
let active = true;
143147
let safety;
148+
// Lets cleanup abort a superseded in-flight request, not just ignore its result.
149+
const controller = new AbortController();
144150
const done = () => {
145151
if ( active ) {
146152
clearTimeout( safety );
@@ -166,7 +172,10 @@ const SiteList = ( {
166172
'/starter_search?builder=' +
167173
encodeURIComponent( editor ) +
168174
'&q=' +
169-
encodeURIComponent( q )
175+
encodeURIComponent( q ),
176+
false,
177+
true,
178+
controller.signal
170179
)
171180
.then( ( res ) => {
172181
if ( ! active ) {
@@ -181,11 +190,18 @@ const SiteList = ( {
181190

182191
fail();
183192
} )
184-
.catch( fail );
185-
}, 600 );
193+
.catch( ( err ) => {
194+
// Aborted = superseded, not a real failure → skip the fallback.
195+
if ( err && err.name === 'AbortError' ) {
196+
return;
197+
}
198+
fail();
199+
} );
200+
}, SEARCH_DEBOUNCE_MS );
186201

187202
return () => {
188203
active = false;
204+
controller.abort();
189205
clearTimeout( timer );
190206
clearTimeout( safety );
191207
};

onboarding/src/utils/rest.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ export const send = ( route, data, simple = false ) => {
55
return requestData( route, simple, data );
66
};
77

8-
export const get = ( route, simple = false, useNonce = true ) => {
9-
return requestData( route, simple, {}, 'GET', useNonce );
8+
export const get = ( route, simple = false, useNonce = true, signal = null ) => {
9+
return requestData( route, simple, {}, 'GET', useNonce, signal );
1010
};
1111

1212
const requestData = async (
1313
route,
1414
simple = false,
1515
data = {},
1616
method = 'POST',
17-
useNonce = true
17+
useNonce = true,
18+
signal = null
1819
) => {
1920
const options = {
2021
method,
@@ -37,6 +38,11 @@ const requestData = async (
3738
options.headers[ 'x-wp-nonce' ] = tiobDash.nonce;
3839
}
3940

41+
// Optional AbortSignal so callers can cancel an in-flight request.
42+
if ( signal ) {
43+
options.signal = signal;
44+
}
45+
4046
if ( 'POST' === method ) {
4147
options.body = JSON.stringify( data );
4248
}

0 commit comments

Comments
 (0)