Loading custom components dynamically in Angular with SVG: a how-to guide

Looking for a way to dynamically load SVG items with ease.

The items needed are quite simple. Here's a basic template:

<svg:rect [attr.x]="x" [attr.y]="y" width="10" height="10" />

Component Class Example:

export class DraggableSvgItemComponent implements OnInit {

  x: number = 0;
  y: number = 0;

  constructor() { }

  ngOnInit() {
  }

}

Showing how the container component template is structured:

<svg attr.height.px="{{height}}" attr.width.px="{{width}}">
    <svg:g app-draggable-svg-item *ngFor="let d of draggables" />
</svg>

Here's the process used to generate the items from within the container component:

// commands <- load fun stuff with x and y coordinates
var toSet = new Array<DraggableSvgItemComponent>();
commands.forEach((value) => {
  if (value instanceof ZPL2.GraphicShapeBase) {
    var toAdd = new DraggableSvgItemComponent();
    toAdd.x = value.x;
    toAdd.y = value.y;

    console.log(toAdd);
    toSet.push(toAdd);
  }
});

this.draggables = toSet;

Even though the console log confirms that x and y have non zero values like

DraggableSvgItemComponent {x: 100, y: 50}
, the output still displays a square in the top-left corner with both x and y values set to 0.

When placing the <rect> directly on the canvas without utilizing a separate component, it functions correctly. However, using a different component is necessary to handle various svg elements.

Any idea on what could be causing the issue with the value bindings?

Answer â„–1

Instead of manually creating instances of the DraggableSvgItemComponent, you can have them generated automatically as children of the <svg:g> elements by defining the component selector as an attribute selector. To enable data binding for the x and y properties, you can use the Input decorator.

@Component({
  selector: '[draggable-svg-item]',
  template: `<svg:rect [attr.x]="x" [attr.y]="y" width="10" height="10" />`
})
export class DraggableSvgItemComponent {
  @Input() x: number = 0;
  @Input() y: number = 0;
}

In the parent component, the draggables array can simply contain position objects:

export class AppComponent {
  width = 200;
  height = 200;
  draggables = [
    { x: 5, y: 0 },
    { x: 20, y: 30 },
    { x: 0, y: 20 },
    { x: 24, y: 8 },
  ];
}

These positions are then bound to the child components using property binding:

<svg [attr.height.px]="height" [attr.width.px]="width">
    <svg:g draggable-svg-item [x]="d.x" [y]="d.y" *ngFor="let d of draggables" />
</svg>

Check out a demo on this stackblitz.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a String Array and linking it to an Input Field

I'm currently working on a code that involves mapping through an array of strings using observables. My objective is to display the value from this array inside an input field. However, despite being able to view the array in the console, I encountere ...

Running a function before triggering a refresh in Angular 2/4

When a user clicks or presses the F5 button on an HTML page, the page refreshes. However, before the refresh occurs, I want to execute a function or display a simple alert. The user can trigger a refresh by clicking the refresh button, pressing F5, or usi ...

Utilize TypeScript function types in React for enhanced functionality

I have made the decision to refactor a project that was originally created with vanilla JavaScript and now I want to transition it to TypeScript. One issue I am facing is how to pass a function as a type on an interface. Although I referred to the TypeScr ...

Learn how to trigger an HTTP exception after a failed command in a saga with NestJS CQRS

Currently utilizing the NestJS CQRS pattern to handle interactions between User and UserProfile entities within my system. The setup consists of an API Gateway NestJS server along with dedicated NestJS servers for each microservice (User, UserProfile, etc. ...

Implementing type inference for response.locals in Express with TypeScript

I need to define types for my response.locals in order to add data to the request-response cycle. This is what I attempted: // ./types/express/index.d.ts declare global { declare namespace Express { interface Response { locals: { ...

Implementing a builder pattern with @Ngrx/Store

Feeling a bit uncertain... I'm wondering if it's suitable, awesome or not advisable to employ a builder pattern to retrieve API response and then apply the builder pattern on that response before storing it in @ngrx/store? And later on when acces ...

Implementing data waiting strategy in Vue component using TypeScript for rendering

When working with the first component, I encountered a scenario where I needed to open a new page using the router functionality: In Component_1.vue: let route = this.$router.resolve({ name: 'Schedule', params : { id: (this.schedule[0].schedule ...

Implementing ngFor to Iterate Through a JSON Object in Angular 6

Iterate through the object list retrieved from a JSON object Here is the JSON object that I have fetched: { "0": { "0": null, "1": "Consolidated Statements of Changes in Stockholders\u2019 Deficit", "2": null, "3": "", "4": "" ...

Problems encountered while building TypeScript on Azure's Hosted Agent

I'm currently working on an ASP.NET MVC application built in .Net5 that utilizes TypeScript files and includes NuGet package references for the following: <PackageReference Include="BuildBundlerMinifier" Version="3.2.449" /> ...

How can the `ng new --collection` command be utilized in Angular?

Can you explain the purpose of using the ng new --collection command in Angular? And can you provide instructions on how to use it in the command prompt? If you have any knowledge about this, please share with me. ...

The Angular Material autocomplete panel does not disappear when autocomplete is hidden within a scrollable region

https://i.sstatic.net/0eS4M.gif Having encountered a bug, I have raised an issue for it (https://github.com/angular/components/issues/20209). I am reaching out to inquire if there exists any workaround or solution known to anyone. You can observe the pro ...

Error TS2322: The specified type 'Element' cannot be assigned to the type 'boolean'

I'm just beginning to explore TypeScript and I ran into an issue while trying to type my constant dialogFuncMap. I received an error (listed in the comments below). Why am I getting this error if the type of state is boolean? And how can I resolve it ...

The promise catch method does not handle JSON parsing correctly

Utilizing Angular's Http to interact with my API has been successful for handling responses with a status of 200. The data is parsed correctly and outputted as expected within the first .then() block. However, when encountering an error with a status ...

I am a beginner in the world of Typescript/Angular, and I have encountered a compiling error TS2339. It seems that even when the condition *ngIf="x.length > 0;" should be false, the

I'm currently enrolled in a Typescript/Angular course where I am learning about the implementation of "*ngIf". During one of the lessons, the instructor provided an example using an empty array to demonstrate how it fails the condition and results in ...

What is the best way to update placeholders in Angular 8+?

I have a collection of items: a = ['apple', 'mango', 'grape', 'papaya', 'banana', 'cucumber']. An input element is present with a placeholder stating select from fruits (the array elements should ...

The process of invoking the AsyncThunk method within the Reducer method within the same Slice

Within my slice using reduxjs/toolkit, the state contains a ServiceRequest object as well as a ServiceRequest array. My objective is to dispatch a call to a reducer upon loading a component. This reducer will check if the ServiceRequest already exists in ...

Angular 6's subscribe method is causing the UI to not update

I'm currently facing an issue where my component does not refresh the UI after I input data. I always have to manually refresh the page to see the changes. I suspect there might be a problem with the .subscribe method in Angular 6. Previously, when I ...

What is the key to ensuring the content in your canvas adapts to different screen sizes

Greetings! I wanted to extract the values from this specific meta tag: <meta name="viewport" property="viewport" content="width-device-width, initial-scale=1"> To retrieve content from a meta tag using JavaScript, I used the following code snippet: ...

Rollup bundling with Typescript and troublesome rollup-plugin-typescript2 experience

I'm currently facing some unexpected challenges while attempting to extract a small portion of a monorepo into a web client library. The issue seems to be related to the configuration of Rollup, as shown below: import resolve from "rollup-plugin-node ...

Tips for sorting and categorizing information within Angular version 14

When I press "All," I want to see the status of P and step 01, along with its type. Thank you very much. This is in HTML: <mat-form-field appearance="outline"> <mat-select (selectionChange)="onChange($event)"> ...