Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How do I fill a settings autocomplete box from a web API?

I have run into an issue with the AdditiveList/TextInput autocomplete function in the settings. I want to populate the autocomplete from a web API (similar to the BART example, but with live data from the API I am querying), but fetch() (the only supported web-accessing API) is an asynchronous system, as was XHR before it.

 

Unfortunately, the onAutocomplete field requires that the function returns an array. However, I can't work out how to wait for the request to complete from within the callback in fetch().then(); Does anybody have any ideas on how I can complete this?

 

There has been a previous question over a year ago on this, but that went ignored, so whilst this is technically a dupe, there has been no answer that I can find: https://community.fitbit.com/t5/SDK-Development/Settings-google-places-fetch/m-p/2596118#M3348

 

My code:

settings/index.jsx:

import { search } from "../common/apiHelper.js";

function mySettings(props) {
  return (
    <Page>
      <Section
        title={<Text bold align="center">TfL Buses App Settings</Text>}>
        <AdditiveList
          title="Select up to 5 bus stops to check"
          settingsKey="favourite_stops"
          maxItems="5"
          addAction={
            <TextInput
              title="Add a new bus stop"
              label="New Stop"
              placeholder="Type something"
              action="Add Stop"
              onAutocomplete={stopSearch}
            />
          }
        />
      </Section>
    </Page>
  );
}

function stopSearch(value) {
  search(value, function(jsonReply){
    console.log("stopSearch->jsonReply: " + JSON.stringify(jsonReply));
    results = jsonReply.matches;
    
    for (result in results){
      
    }
  });
}

registerSettingsPage(mySettings);

 

common/apiHelper.js:

(there are more exports for other API calls, but search() is the only one used in the settings)

const BASE_URL = "<url_of_api>";

function get(endpoint, queryString, callback){
  var url= BASE_URL;
  url += endpoint;
  url += "?";
  url += queryString;
  
  fetch(url).then(function(response){
    if (response.ok){
      response.json().then(callback)
    }
    else {
      callback({error: true, statusCode: response.status, statusText: response.statusText, body: response.body});
    }
  });
}

export function search(query, callback){
    get("/search", "searchTerm=" + query, function(jsonReply){
      if (jsonReply.error === true){
        // log error for debugger and ignore callback
        console.log(JSON.stringify(jsonReply));
      }
      else {
        // success - return data to callback
        callback(jsonReply);
      }
    });
}

 

Best Answer
0 Votes
0 REPLIES 0