Tricks

Search & load form data from an API

Aug 5, 2022
Z3d0X
Form builder, Integration

This can be accomplished in a few simple steps

  1. Make a Trigger for the search
  2. Fetch the data from an API & Load the data into the form state

If you just want to see the entire code example you can skip to this section

Explanation

Lets see how this can be accomplished with an example:

Search trigger

We are going to start with this very simple form schema. Our goal is to automatically fill the country_region & country_subregion, based on country_name

protected function getFormSchema(): array
{
return [
TextInput::make('country_name'),
TextInput::make('country_region'),
TextInput::make('country_subregion'),
];
}

Our search trigger will be a ->suffixAction() on the TextInput

use Filament\Forms\Components\Actions\Action;
//...
TextInput::make('country_name')
->suffixAction(fn ($state, Closure $set) => Action::make('search-action')
->icon('heroicon-o-search')
->action(function () use ($state, $set) {
//Notice how `$state` & `$set` are injected. These will be used later on
//We will leave this blank for now
})
),

Fetch & load data

Lets just focus on the action.

Action::make('search-action')
->icon('heroicon-o-search')
->action(function () use ($state, $set) {
//$state is state of this(country_name) field, i.e. the search term
 
//Always a good idea to check using blank() whenever using a field state
if (blank($state))
{
//notify the user that they must enter a search term
Filament::notify('danger', 'Please enter a country name');
return;
}
 
//make the request to the api
try {
//Not going into too much detail here,
//because how the data is fetched is up to you and not relevant to filament
$countryData = Http::baseUrl('https://restcountries.com/v3.1/name')
->get($this->data['country_name'], ['fields' => 'region,subregion'])
->throw()
->json('0');
} catch (RequestException $e) {
//notify the user that the api request failed
Filament::notify('danger', 'Unable to find the country');
return;
}
 
//using $set we can set the value of another field
$set('country_region', $countryData['region'] ?? null);
$set('country_subregion', $countryData['subregion'] ?? null);
})

Entire Example Code

protected function getFormSchema(): array
{
return [
TextInput::make('country_name')
->suffixAction(fn ($state, Closure $set) =>
Action::make('search-action')
->icon('heroicon-o-search')
->action(function () use ($state, $set) {
if (blank($state))
{
Filament::notify('danger', 'Please enter a country name');
return;
}
 
try {
$countryData = Http::baseUrl('https://restcountries.com/v3.1/name')
->get($this->data['country_name'], ['fields' => 'region,subregion'])
->throw()
->json('0');
} catch (RequestException $e) {
Filament::notify('danger', 'Unable to find the country');
return;
}
 
$set('country_region', $countryData['region'] ?? null);
$set('country_subregion', $countryData['subregion'] ?? null);
})
),
TextInput::make('country_region'),
TextInput::make('country_subregion'),
];
}

No comments yet…