Make request fire only on reaching requestMinInputLength if requestDebounceDelay set to 0

This commit is contained in:
Tom Nunn 2023-04-16 20:49:46 +01:00
parent bcdef5c1da
commit 4ceda0f92e
6 changed files with 72 additions and 6 deletions

View File

@ -1,5 +1,11 @@
# Changelog
# 4.0.1 (not published yet)
### Enhancements
- When `requestDebounceDelay` is set to 0, a request is sent immediately only when input length reaches `requestMinInputLength`, but not on further typing beyond the minimum.
# 4.0.0
### Enhancements

View File

@ -64,7 +64,10 @@ update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
SelectMsg subMsg ->
Select.updateWith [ Select.request fetchCocktails ] SelectMsg subMsg model.select
Select.updateWith [ Select.request fetchCocktails ]
SelectMsg
subMsg
model.select
|> Tuple.mapFirst (\select -> { model | select = select })

View File

@ -1,6 +1,7 @@
module RequestTest exposing (exampleProgramTest)
import EffectRequestExample as App exposing (Cocktail)
import Expect
import Json.Decode as Decode
import Json.Encode as Encode
import ProgramTest exposing (ProgramTest, SimulatedEffect)
@ -50,6 +51,38 @@ exampleProgramTest =
"https://thecocktaildb.com/api/json/v1/1/search.php?s=Chocolate+Drink"
cocktailsResponse
|> ProgramTest.expectViewHas [ Selector.text "Melt the bar in a small amount of boiling water. Add milk." ]
, Test.test "Setting requestDebounceDelay to 0 sends a request at exactly requestMinInputLength and no more on further typing" <|
\() ->
ProgramTest.createElement
{ init = App.init
, update =
\msg model ->
case msg of
App.SelectMsg subMsg ->
Select.Effect.updateWith
[ Select.Effect.request App.FetchCocktails
, Select.Effect.requestDebounceDelay 0
, Select.Effect.requestMinInputLength 3
]
App.SelectMsg
subMsg
model.select
|> Tuple.mapBoth (\select -> { model | select = select }) App.SelectEffect
, view = App.view
}
|> ProgramTest.withSimulatedEffects simulateEffect
|> ProgramTest.start (Encode.object [])
|> focusInput
|> ProgramTest.fillIn "" "Find a cocktail" "Cho"
|> ProgramTest.advanceTime 0
|> ProgramTest.ensureHttpRequestWasMade "GET" "https://thecocktaildb.com/api/json/v1/1/search.php?s=Cho"
|> ProgramTest.simulateHttpOk "GET" "https://thecocktaildb.com/api/json/v1/1/search.php?s=Cho" cocktailsResponse
|> ProgramTest.fillIn "" "Find a cocktail" "Choc"
|> ProgramTest.advanceTime 500
|> ProgramTest.ensureHttpRequests "GET" "https://thecocktaildb.com/api/json/v1/1/search.php?s=Choc" (Expect.equal [])
|> ProgramTest.fillIn "" "Find a cocktail" "Chocolate"
|> ProgramTest.advanceTime 500
|> ProgramTest.expectHttpRequests "GET" "https://thecocktaildb.com/api/json/v1/1/search.php?s=Chocolate" (Expect.equal [])
]

View File

@ -56,7 +56,19 @@ update_ { request, requestMinInputLength, debounceRequest, onFocus, onLoseFocus,
, Effect.batch
[ case request of
Just _ ->
if String.length val >= requestMinInputLength then
if debounceRequest == 0 then
if
String.length val
== requestMinInputLength
&& String.length val
> String.length (Model.toInputValue model)
then
Effect.Debounce (InputDebounceReturned >> tagger) 0 val
else
Effect.none
else if String.length val >= requestMinInputLength then
Effect.Debounce (InputDebounceReturned >> tagger) debounceRequest val
else

View File

@ -307,11 +307,17 @@ request effect =
UpdateOptions.Request effect
{-| Configure debouncing for the request. How long should we wait in milliseconds after the user stops typing to send the request? Default is 300.
{-| Configure debouncing for the request.
How long should we wait in milliseconds after the user stops typing to send the request? Default is 300.
If set to 0, a request will be immediately whenever the input length reaches requestMinInputLength,
no further requests will be sent on typing beyond that length and beyond that filtering will be done client side.
This can make the input feel more responsive (options appear sooner),
but may result in a larger result payload requiring more filtering on the client side.
Select.updateWith
[ Select.request fetchThings
, Select.requestDebounceDelay 500
, Select.requestDebounceDelay 200
]
SelectMsg
subMsg

View File

@ -164,11 +164,17 @@ request effect =
UpdateOptions.Request effect
{-| Configure debouncing for the request. How long should we wait in milliseconds after the user stops typing to send the request? Default is 300.
{-| Configure debouncing for the request.
How long should we wait in milliseconds after the user stops typing to send the request? Default is 300.
If set to 0, a request will be immediately whenever the input length reaches requestMinInputLength,
no further requests will be sent on typing beyond that length and beyond that filtering will be done client side.
This can make the input feel more responsive (options appear sooner),
but may result in a larger result payload requiring more filtering on the client side.
Select.Effect.updateWith
[ Select.Effect.request FetchThings
, Select.Effect.requestDebounceDelay 500
, Select.Effect.requestDebounceDelay 200
]
SelectMsg
subMsg