Logo

dev-resources.site

for different kinds of informations.

πŸš€ Rendering Dynamic Components in Ember.js with Embroider

Published at
7/3/2024
Categories
ember
embroider
javascript
webdev
Author
rabbi50
Categories
4 categories in total
ember
open
embroider
open
javascript
open
webdev
open
Author
7 person written this
rabbi50
open
πŸš€ Rendering Dynamic Components in Ember.js with Embroider

Hey folks! πŸ‘‹

Today, I want to share a powerful technique for rendering dynamic components in Ember.js, especially when using Embroider, Ember's next-generation build system. This approach is particularly useful when the component names are retrieved from an API, and you need to render these components dynamically.

Why Dynamic Components?

Dynamic components allow you to build flexible and reusable applications. They enable you to determine which component to render at runtime, based on data or other conditions. This is particularly useful in scenarios like content management systems or dashboards, where the UI components can change based on user input or configuration.

Using Embroider for Dynamic Components

Embroider provides tools like importSync and ensureSafeComponent to help with dynamic component rendering. Here's how you can leverage these tools to render components dynamically in Ember.js.

Step-by-Step Implementation

1. Update ember-cli-build.js to Allow Unsafe Dynamic Components

First, ensure that your ember-cli-build.js file is configured correctly to allow unsafe dynamic components.

ember-cli-build.js

'use strict';
  const { Webpack } = require('@embroider/webpack');
  const EmberApp = require('ember-cli/lib/broccoli/ember-app');

  module.exports = function (defaults) {
    const app = new EmberApp(defaults, {
      ....
    });

    return require('@embroider/compat').compatBuild(app, Webpack, {
      .....
      allowUnsafeDynamicComponents: true,
    });
  };
Enter fullscreen mode Exit fullscreen mode

Explanation

  • allowUnsafeDynamicComponents: This option enables the use of dynamic components in your application, which is crucial for rendering components based on runtime data.

2. Create a Dynamic Component

First, create a dynamic component that will handle the rendering of other components based on the name provided.

app/components/dynamic-component.js

import Component from "@glimmer/component";
import { ensureSafeComponent } from "@embroider/util";
import { importSync } from "@embroider/macros";
import { tracked } from "@glimmer/tracking";

export default class DynamicComponent extends Component {
  get componentName() {
    return this.args.componentName || null;
  }

  get argsData() {
    return this.args.argsData || null;
  }

  get componentLabel() {
    if (this.componentName) {
      let module = importSync(`/components/${this.componentName}`);
      return ensureSafeComponent(module.default, this);
    }
    return null;
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation

  • importSync: This function allows synchronous dynamic imports. It ensures the component module is available at runtime.

  • ensureSafeComponent: This utility ensures that the component is safe to render, which is particularly important when dealing with dynamic components.

  • get componentName: This property holds the name of the component to be rendered which you passed as args. You can update this property based on the data received from an API.

3. Dynamic Component Template

Create the template for the dynamic component to render the desired component dynamically.

app/templates/components/dynamic-component.hbs

{{#if this.componentLabel}}
    <this.componentLabel @argsData={{this.argsData}} />
{{/if}}
Enter fullscreen mode Exit fullscreen mode

Explanation

  • this.componentLabel: This invokes the dynamically imported component.
  • @argsData: This passes any necessary data to the dynamically rendered component.

Example Usage

  • Here’s an example of how you might use this DynamicComponent in your application.

app/controllers/application.js

import Controller from "@ember/controller";
import { action } from "@ember/object";
import { tracked } from "@glimmer/tracking";

export default class ApplicationController extends Controller {
  @tracked dynamicComponentName = "component_one/nested_component";
  @tracked argsData = { key: "value" };

  @action
  updateComponentName(newComponentName) {
    this.dynamicComponentName = newComponentName;
  }
}
Enter fullscreen mode Exit fullscreen mode

app/templates/application.hbs

<DynamicComponent
  @componentName={{this.dynamicComponentName}}
  @argsData={{this.argsData}}
/>

<button
  {{on "click" (fn this.updateComponentName "component_two/another_component")}}
>Switch Component</button>

Enter fullscreen mode Exit fullscreen mode

Explanation

  • DynamicComponent: This component renders the dynamic component based on the componentName and argsData passed to it.
  • updateComponentName: This action updates the component name, demonstrating how you can switch components dynamically.

Conclusion

Rendering dynamic components in Ember.js using Embroider's utilities like importSync and ensureSafeComponent provides a flexible and powerful way to build dynamic and interactive applications. This approach is particularly beneficial in scenarios where component names are retrieved from an API or other dynamic sources.

Feel free to reach out if you have any questions or need further assistance with Ember.js and Embroider! 😊

Here's the complete code: Repo

Give a star to the repository if you find it helpful. Your support is greatly appreciated! 😊

ember Article's
30 articles in total
Favicon
Ember.js in 60 Seconds
Favicon
Intro to Ember.js Components
Favicon
The Top 7 Reasons You Should NOT Use Ember.js on Your Next Project
Favicon
why don't we have a slack channel?
Favicon
Installing EmberJS v2 addons from GitHub forks using PNPM
Favicon
Add custom layer to embe-leaflet
Favicon
Why Ember Wins My Heart Over React ❀️ And Maybe Yours Too!
Favicon
Migrate from ember-cli-deploy-sentry to sentry-cli
Favicon
ERR_PNPM_BAD_PM_VERSION This project is configured to use vX of pnpm. Your current pnpm is vY
Favicon
Fixing Package Dependencies
Favicon
React inside Ember - The Second Chapter
Favicon
πŸš€ Rendering Dynamic Components in Ember.js with Embroider
Favicon
How to use the new Ember theme for QUnit
Favicon
Effects in Ember
Favicon
unsupported ambiguity between helper and component
Favicon
12 common Ember errors to know: A definitive guide on handling EmberJS errors
Favicon
Demystifying Ember.js Development: How to Hire the Right Developer for YourΒ Project
Favicon
Is Angular.js or Ember.js the better choice for JavaScript frameworks?
Favicon
Integrations Series: Authentication And Connection
Favicon
Support for in/inter page linking / scrolling in EmberJS
Favicon
Ember-cli config
Favicon
GraphQL in Your Ember App with Glimmer Apollo
Favicon
Setting up Tailwind, the easy way
Favicon
Context leaking in EmberJS tests
Favicon
What to use instead of `@ember/string`
Favicon
Ember Language Server in Emacs
Favicon
Why Ember.js is designed for Enterprise Software Development
Favicon
Demystifying Ember Serialization: A Comprehensive Guide
Favicon
ember-cli is stuck on certain version
Favicon
React micro-frontend in ember app - Part 2

Featured ones: