lantech's avatar

Laravel Nova - Field Badge Array problem

Newbie here :)

I cant figure out why a function works in one Field(Select) but not in another(Badge), same function to return an array...

This works:

Select::make('inspection_carried_out')
                    ->options(function () {
                        return array_filter(\App\Models\Status::pluck('name', 'id')->toArray());
                    }),

But this doesn't (why?):

Badge::make('external_company_inspection_agreement')
                ->map(function () {
                    return array_filter(\App\Models\Status::pluck('badge', 'id')->toArray());
                })

Error: Laravel\Nova\Fields\badge::map(): Argument #1 {$map} must of type array, Closure given.

0 likes
17 replies
hellolara's avatar

I might be wrong, but I believe map() expects an array. You're giving it a function that returns an array. It's not exactly the same thing.

This works for options() because options is expecting a function.

I hope this helps!

lantech's avatar

@hellolara

Yes, I get that but in the documentation the ->map and the ->options both expects an array (identical if I see correct)

Thats why I can't understand why a function works in ->options but not in ->map

hellolara's avatar

@lantech It's ok, so, let's start with formatting :)

To format 1 line of code, use what is called a backtick (`) before and after the code, like so code(). For longer code, you have to use three of them at the start, and three of them at the end (```)

// this is how you get multiple lines of code
// very helpful

This should offer more information: https://www.markdownguide.org/basic-syntax/#code


As for where to put $badgeMap, just above where you're using it is fine. In other words, if you replace your Badge::. code with

$badgeMap = \App\Models\Status::pluck('badge', 'id')->toArray();
$badgeMap[null] = 'info'; // Add default for null

Badge::make('external_company_inspection_agreement')
    ->map($badgeMap);

you should be fine.

abexo's avatar

The error indicates that you're passing a closure (the anonymous function you've got in there), but the method expects a plain associative array instead (the array directly passed, rather than passing the function itself).

lantech's avatar

Thank you for your answers, anybody got a solution to how I could achieve desired goal?

lantech's avatar

If I do this instead:

Badge::make('external_company_inspection_agreement')
				->map(\App\Models\Status::all()->pluck('name', 'id')->toArray())

I don't get the same error...Instead I get this: Error trying to find type [] inside of the field's type mapping.

I think it gets the correct array but it's missing a badge for the NULL value I could fix this in a manual array by adding:

null => 'info',

But how can I add this to the dynamic array?

->map(\App\Models\Status::all()->pluck('name', 'id')->toArray())

I tried this:

->map(function () {
$array_badge = \App\Models\Status::pluck('badge','id')->toArray();
$array_badge[null] = "info";
return $array_badge;
}),

But then I get back to the original problem (functio when expecting array...?) Error: Laravel\Nova\Fields\badge::map(): Argument #1 {$map} must of type array, Closure given.

lantech's avatar

It's working now! Thank you sooo much! 🙏

1 like
hellolara's avatar
Level 9

I think that you're on the right track. The only thing that I can think of that is not working is that you have to define the array before passing it to map(). Try:

$badgeMap = \App\Models\Status::pluck('badge', 'id')->toArray();
$badgeMap[null] = 'info'; // Add default for null

Badge::make('external_company_inspection_agreement')
    ->map($badgeMap);

This should work

lantech's avatar

@hellolara

I'm a total newbie... where can I put the:

$badgeMap = \App\Models\Status::pluck('badge', 'id')->toArray();
$badgeMap[null] = 'info'; // Add default for null

Doesn't work inside the the

Badge::make

nor outside the

public function fields(NovaRequest $request): array
lantech's avatar

I found it... Inside: public function fields(NovaRequest $request): array { but before: return [

hellolara's avatar

@lantech

It's kind of difficult to figure out what the issue is without knowing what the db is like, but you can add a temporary Nova field to debug:

Text::make('Debug', function () {
    return $this->external_company_inspection_agreement;
}),
lantech's avatar

@hellolara

I appreciate your time and knowledge and trying to help 👍

CREATE TABLE `statuses` (
  `id` bigint(20) NOT NULL,
  `name` varchar(255) NOT NULL,
  `badge` varchar(255) DEFAULT NULL,
  `icon` varchar(255) DEFAULT NULL,
  `color` varchar(255) DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

--
-- Dumpning av Data i tabell `statuses`
--

INSERT INTO `statuses` (`id`, `name`, `badge`, `icon`, `color`, `created_at`, `updated_at`) VALUES
(10, 'Ja', 'success', 'check-badge', '#02c902', '2025-04-20 10:08:44', '2025-04-20 10:08:44'),
(11, 'Nej', 'danger', 'x-circle', '#c90202', '2025-04-20 10:08:44', '2025-04-20 10:08:44'),
(12, 'Vet ej', 'warning', 'exclamation-circle', '#cac302', '2025-04-20 10:08:44', '2025-04-24 21:42:48'),
(20, 'Allvarlig', 'danger', 'x-circle', '#eb0202', '2025-04-20 10:08:44', '2025-04-20 10:08:44'),
(21, 'Mindre', 'warning', 'exclamation-circle', '#ebdb02', '2025-04-20 10:08:44', '2025-04-20 10:08:44'),
(22, 'Minimal', 'success', 'check-badge', '#3ceb02', '2025-04-20 10:08:44', '2025-04-20 10:08:44'),
(99, 'n/a', 'info', 'information-circle', '#00fbff', '2025-04-20 10:08:44', '2025-04-24 22:33:20');

I created the debug field but it's returns: —

hellolara's avatar

@lantech — usually means null.

Let's try from the basics. Are you getting the fields when you use ::all() instead of ::pluck()?

Don't worry about the formatting for now. Focus on getting the data.

die(var_dump($result)) to see what you're getting

EDIT: I see that it's working. Good job :)

I'll live this reply here just in case someone might need this nudge some time in the future

Please or to participate in this conversation.