Playing Next Lesson In
seconds

EdgeJS Components #2.1

Component State & Passing State from EdgeJS to ApineJS

In This Lesson

We'll take a look at how we can define and manage state within EdgeJS Components. We'll also learn how we can pass single properties or full objects from EdgeJS to AlpineJS and our client-side scripts.

Created by
@tomgobich
Published

In this lesson, we’ll focus on managing component state using EdgeJS and how we can pass state from EdgeJS into AlpineJS.

EdgeJS State

The easiest way that we can set state within an EdgeJS Component is via the set tag (@set). The set tag is going to allow us to set a local variable that will only exist inside of this particular component.

When defined at the top of our component file, it’ll be unique to its particular component instance and won’t be shared with other components or pages.

When defined inside a block, like an @each or @if, it’ll exist only inside that block. Similar to a tradition JavaScript variable.

@set('breadcrumbs', false)
Copied!

The set tag is a simple method, which tags the variable’s name as the first argument and the value as the second argument. The value here can be a number of different valid JavaScript values, including arrow functions, objects, arrays, and primitive types.

Passing Primitives from EdgeJS to AlpineJS

Let’s say we want to pass the EdgeJS variable we’ve set above, called breadcrumbs, as the default value for our breadcrumbs variable in our AlpineJS state. Since the value is a primitive type, all we’ll need to do is drop it directly from EdgeJS into the value position for AlpineJS.

@set('breadcrumbs', false)

<header 
  x-data="{ breadcrumbs: {{ breadcrumbs }} }" 
  x-data="{ breadcrumbs: true }" 
  class="bg-gray-100 p-6 -mx-6 mb-6 rounded-md">
  @if (title != 'Home')
    <a 
      x-show="breadcrumbs"
      href="/" 
      class="text-xs"
      @click.prevent="breadcrumbs = false">
      Home
    </a>
  @endif
  
  <h1 class="text-2xl font-bold">{{ titleCase(title) }}</h1>
</header>
Copied!
  • resources
  • views
  • components
  • layouts
  • app.edge

When EdgeJS renders this out on the server-side, it’ll end up looking like the below.

<header 
  x-data="{ breadcrumbs: false }" 
  class="bg-gray-100 p-6 -mx-6 mb-6 rounded-md">
  <a 
    x-show="breadcrumbs"
    href="/" 
    class="text-xs"
    @click.prevent="breadcrumbs = false">
    Home
  </a>
  
  <h1 class="text-2xl font-bold">Home</h1>
</header>
Copied!

Notice how {{ breadcrumbs }} simply renders to false.

Passing Objects & Arrays from EdgeJS to AlpineJS

When it comes to non-primitive types, however, things get a little more complicated because we can’t just directly pass an object or array from our server to client via HTML.

What Won’t Work

If we were to try passing an object from EdgeJS directly into AlpineJS as it’s state, like the below.

@set('data', {
  breadcrumbs: false
})

<header 
  x-data="{{ breadcrumbs }}" 
  class="bg-gray-100 p-6 -mx-6 mb-6 rounded-md">
  @if (title != 'Home')
    <a 
      x-show="breadcrumbs"
      href="/" 
      class="text-xs"
      @click.prevent="breadcrumbs = false">
      Home
    </a>
  @endif
  
  <h1 class="text-2xl font-bold">{{ titleCase(title) }}</h1>
</header>
Copied!
  • resources
  • views
  • components
  • layouts
  • app.edge

The final HTML output would end invalid, like the below.

<header 
  x-data="[object Object]" 
  class="bg-gray-100 p-6 -mx-6 mb-6 rounded-md">
  <a 
    x-show="breadcrumbs"
    href="/" 
    class="text-xs"
    @click.prevent="breadcrumbs = false">
    Home
  </a>
  
  <h1 class="text-2xl font-bold">Home</h1>
</header>
Copied!

Notice, how our EdgeJS data rendered as [object Object].

What Will Work

To remedy this, all we need to do is convert our object, or array, to a string. Though EdgeJS will be rendering a string on the server-side, once it hit’s our client-side it’ll come through as the object we had intended.

EdgeJS also has a global helper to aid with this, called stringify, which will not only convert our object to a string, but will also escape unsafe HTML characters to prevent XSS attacks.

@set('data', {
  breadcrumbs: false
})

<header 
  x-data="{{ stringify(breadcrumbs) }}" 
  class="bg-gray-100 p-6 -mx-6 mb-6 rounded-md">
  @if (title != 'Home')
    <a 
      x-show="breadcrumbs"
      href="/" 
      class="text-xs"
      @click.prevent="breadcrumbs = false">
      Home
    </a>
  @endif
  
  <h1 class="text-2xl font-bold">{{ titleCase(title) }}</h1>
</header>
Copied!
  • resources
  • views
  • components
  • layouts
  • app.edge

Using stringify, EdgeJS will now render the above as the below.

<header 
  x-data="{ breadcrumbs: false }" 
  class="bg-gray-100 p-6 -mx-6 mb-6 rounded-md">
  <a 
    x-show="breadcrumbs"
    href="/" 
    class="text-xs"
    @click.prevent="breadcrumbs = false">
    Home
  </a>
  
  <h1 class="text-2xl font-bold">Home</h1>
</header>
Copied!

Thus, allowing us to easily pass non-primitive values from EdgeJS to AlpineJS.

Join the Discussion 0 comments

Create a free account to join in on the discussion
robot comment bubble

Be the first to comment!