'R Shiny update selectizeinput choices based on geocoded text

I'm trying to update the choices for selectizeinput based on geocoding in the search field. The problem is that it doesn't register I've inputted anything, but when I hardcode a fake address on the server side it works. I've tried to make the choices reactive using tidygeocoder, but it doesn't register anytime I type anything into the search field.

Here is a reprex:

library(shiny)
library(shinyWidgets)
library(tidygeocoder)

ui <- fluidPage(
  selectizeInput(
    "search",
    label = NULL,
    choices = "",
    multiple = FALSE,
    selected = character(0),
    options = list(allowEmptyOption = FALSE, placeholder = "SEARCH...")
  )
)

server <- function(input, output, session) {
  
  address_choices <- reactive({
    tidygeocoder::geo(
      input$search,
      method = "osm",
      limit = 5,
      full_results = TRUE
    )
  })
  
  observe({
    req(address_choices())
    current_selected <- isolate(input$search)
    updateSelectizeInput(
      session,
      "search",
      choices = address_choices()$display_name,
      selected = current_selected,
      server = TRUE
    )
  })
  
  
}
shinyApp(ui = ui, server = server)

Result:

It shows nothing no matter what I type in.

enter image description here

Hardcoded Address

The hardcoded version shows the intended result

  address_choices <- reactive({
    tidygeocoder::geo(
      "110 Susan",
      method = "osm",
      limit = 5,
      full_results = TRUE
    )
  })

Hardcoded Results

The drop down shows what should happen when I type "110 Susan"

enter image description here

I've also tried to include if else statements so that it doesn't run when input$search is blank (Which is the default), but that doesn't work. Maybe I shouldn't be using a reactive statement? I'm not quite sure. It just doesn't register input$search after I type.



Solution 1:[1]

The issue is input$search is not populated when you are typing the text. Since it is selectizeInput, the value is only filled when any dropdown option is selected so tidygeocoder::geo function is never called.

Based on help from this post , we can use the javascript function to capture the text while we are typing and use it to get the address.

library(shiny)
library(shinyWidgets)
library(tidygeocoder)

js <- '
      $(document).on("keyup", function(e) {
        minChars = 4;
        tag1 = document.activeElement.getAttribute("id");
        val1 = document.activeElement.value;
        if (tag1 == "search-selectized") {
          if (Math.sign(val1.length +1 - minChars) == 1) {
            obj = { "val": val1 };
            Shiny.onInputChange("valueEntered", obj);
          }
        }
      });'
      
ui <- fluidPage(
  tags$script(js),
  selectizeInput(
    "search",
    label = NULL,
    choices = "",
    multiple = FALSE,
    selected = character(0),
    options = list(allowEmptyOption = FALSE, placeholder = "SEARCH...")
  )
)

server <- function(input, output, session) {
  
  address_choices <- reactive({
    req(input$valueEntered$val)
    tidygeocoder::geo(
      input$valueEntered$val,
      method = "osm",
      limit = 5,
      full_results = TRUE
    )
  })
  
  observe({
    req(address_choices())
    current_selected <- isolate(input$search)
    updateSelectizeInput(
      session,
      "search",
      choices = address_choices()$display_name,
      selected = current_selected,
      server = TRUE
    )
  })
}
shinyApp(ui = ui, server = server)

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ronak Shah