What is the best way to manage multiple directives from a parent component?

Within my app-landing component, I have implemented multiple typeOut directives. These directives are responsible for gradually writing out text within their respective elements. While this functionality is working as intended, I now seek to exert control over the order in which the text is written.

My goal is to enable the app-landing component (or any parent component containing typeOut directives) to maintain an array of these directives. This array should facilitate the ability to invoke each directive's function to sequentially write out text.

Despite my attempts with inputs, outputs, and services, I find myself unsure of the correct approach.

landing.component.ts

  <h1 class="fontSize1">
    <p style="display:none;">{{title.string}}</p>
    <strong>
      <pre typeOut="{{title.ascii}}" typeClump="10" typeOrder="1" typeDelay="0.1"></pre>
    </strong>
  </h1>
  <h2 class="fontSize1">
    <p style="display:none;">{{subtitle.string}}</p>
    <pre typeOut="{{subtitle.ascii}}" typeOrder="1" typeDelay="1"></pre>
  </h2>
</header>
<aside class="portrait">
  <pre class="fontSize2" typeOut="{{portrait.ascii}}" typeClump="10" typeOrder="1" typeDelay="0.1"></pre>
</aside>

type-out.directive.ts

import { Directive, Input, ElementRef, Output, EventEmitter } from '@angular/core';
import { delay, asyncForEach } from '../async';

export interface typeOutObj { order: number, write: any, finished: boolean };

@Directive({
  selector: '[typeOut]'
})
export class TypeOutDirective {
  private dom;
  @Input('typeOut') text: string;
  @Input('typeClump') clump: number;
  @Input('typeOrder') order: number;
  @Input('typeDelay') delay: number;
  @Output() typeObj = new EventEmitter<typeOutObj>();
  typeFinished: boolean;
  charArr = [];


  write = async () => {
    let clump = {
      max: this.clump == undefined ? 0 : this.clump,
      current: 0
    }

    await asyncForEach(this.charArr, async (char) => {
      if (this.typeFinished == false) {
        if (clump.current >= clump.max) {
          clump.current = 0;
          await delay(this.delay == undefined ? 0 : this.delay);
        }
        clump.current++;
        this.dom.innerHTML += char;
      }
    });
  }



  constructor(el: ElementRef) {
    this.dom = el.nativeElement;
    this.dom.innerHTML = '';
    this.typeFinished = false;
  }
  ngAfterContentInit() {
    this.charArr = this.text.split('');
  }

  ngAfterViewInit(): void {
    this.write().then(() => {
      this.typeFinished = true;

      this.typeObj.emit({
        order: this.order,
        write: this.write(),
        finished: this.typeFinished
      });
    });
  }

  ngOnInit() {

  }

}

type-out.service.ts (not sure if I'm going right with this one)

import { Injectable, Input } from '@angular/core';
import { typeOutObj } from './type-out.directive';

@Injectable({
  providedIn: 'root'
})
export class TypeOutService {
  @Input() typeOut: typeOutObj;

  typeOuts: [typeOutObj];

  constructor() {

  }
}

Answer №1

If you want to create a chain-like effect, consider implementing the following steps:

@Output() typingFinished = new EventEmitter<Any>();
@Input() previous;

Include these lines in your directive and make sure to pass a reference for the previous element to your directive.

<pre typeOut="{{title.ascii}}" typeClump="10" typeOrder="1" typeDelay="0.1" #firstDirective></pre>
<pre typeOut="{{subtitle.ascii}}" typeOrder="1" typeDelay="1" #secondDirective [previous]="firstDirective"></pre>
<pre typeOut="{{subtitle.ascii}}" typeOrder="1" typeDelay="1" #thirdDirective [previous]="secondDirective "></pre>

Once the typing is finished, emit an event from the directive and subscribe to this event of the previous directive.

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

When using Next.js and Jest, an error may occur stating "Element type is invalid: expected a string or a class/function but got an object."

I am currently in the process of setting up unit tests for my Next.js project. I have carefully followed the guidelines provided in the official documentation on testing. The issue I'm encountering appears to be related to either the configuration it ...

Accessing dynamically inserted child components in Angular 2.0

Currently, I am utilizing this sample to dynamically generate components within my application. export class App { @ViewChild('placeholder', {read: ViewContainerRef}) viewContainerRef; private componentFactory: ComponentFactory<any> ...

What is the best way to allocate string types from an enum using Typescript?

Within my code, I have an enum that includes a collection of strings export enum apiErrors { INVALID_SHAPE = "INVALID_SHAPE", NOT_FOUND = "NOT_FOUND", EXISTS = "EXISTS", INVALID_AUTH = "INVALID_AUTH", INTERNAL_SERVER_ERROR = "INTERNAL_ ...

Dynamic TypeScript property that can only be assigned values from an array during runtime

I'm currently struggling with specifying allowed values for a property in TypeScript. Within my interface, I have statically typed the property like this: interface SomeInterface{ prop: "bell" | "edit" | "log-out" } However, I am looking for a w ...

Circular dependency in Angular occurs when there is a loop in the way dependencies are injected

I am facing an issue with injecting dependencies into the interceptor. Specifically, I am trying to inject TranslateService into HttpErrorInterceptor, but encountering a cyclic dependency error. Interestingly, when I remove the TranslateService injection, ...

Unusual problem with accessing Object values in vscode using typescript

When attempting to write Object.values in TypeScript, I encounter a visual error (although it compiles without issues). https://example.com/image1.png I have tried searching online and restarting vscode, and here is my current tsconfig.json. https://exa ...

JavaScript - Cannot access the 'name' property on an empty object

I am currently following a React tutorial that demonstrates how to create a useForm hook for linking form input to state. Here is the implementation of the hook: const useForm = (initial = {}) => { const [inputs, setInputs] = useState(initial) ...

TypeScript primitive type is a fundamental data type within the

Does TypeScript have a predefined "primitive" type or similar concept? Like type primitive = 'number' | 'boolean' | 'string';. I'm aware I could define it manually, but having it built-in would be neat. ...

Creating a Class in REACT

Hello fellow coding enthusiasts, I am facing a minor issue. I am relatively new to REACT and Typescript, which is why I need some assistance with the following code implementation. I require the code to be transformed into a class for reusability purposes ...

Struggling with TypeScript declaration files has been a challenge for me

I'm encountering an issue with using the trace function in my TypeScript code. The function has been declared in a .d.ts file as shown below: declare function trace(arg: string | number | boolean); declare function trace(arg: { id: number; name: strin ...

Typescript objects may contain keys that are dependent on certain parameters

I have a challenge with constructing an object that requires querying multiple database tables, resulting in a time-consuming process. To address this issue, clients of the object need to specify which specific parts they require. For example, let's c ...

What is the best way to sort through an Array of photo filenames?

https://i.sstatic.net/04cws.pngI have a list of image names that contain UUIDs. images [ "auditid_626_UUID_666666_time__1582577405550.jpg", "auditid_626_UUID_999999_time__1582577405554.jpg", "auditid_626_UUID_999999_time__15825 ...

Tips for saving multiple pieces of data in a single field with Laravel

Is it possible to save multiple data at once using a simple form? controller $status= new PostTable(); $status->language = $request->language; blade <input type="checkbox" value="hindi" name="language[]" id="language"> Hindi model pro ...

Converting base64 dataUrls into images using typescript

When using ng2-image cropper, it does not accept the "src" attribute and instead requires the "image" attribute. As a result, if a dataUrl is provided, the image will not display in the cropper. I am utilizing the camera to capture an image and obtaining ...

Creating a primary index file as part of the package building process in a node environment

Currently, I have a software package that creates the following directory structure: package_name -- README.md -- package.json ---- /dist ---- /node_modules Unfortunately, this package cannot be used by consumers because it lacks an index.js file in the r ...

Navigating with multiple parameters in Angular 7 routing

I am currently facing an issue where I need to navigate to the same component with different parameters. Although I can subscribe to the params through the ActivatedRoute, I'm encountering a problem when trying to call router.navigate within the subsc ...

Utilize annotations for both request and response filters to enable client-side routing in Quarkus for forwarding purposes

Currently, I am utilizing Quarkus version 3.4.3 to serve as the backend for my REST endpoints and also host my Angular SPA which acts as a simple interface for interacting with those rest endpoints. The issue I am facing is quite common - I need client-si ...

Error in Angular 5: Google Maps not defined

Having trouble implementing Google Maps on my Angular 5 app. Upon loading the view, I am encountering this error in the JavaScript console: LoginComponent_Host.ngfactory.js? [sm]:1 ERROR ReferenceError: google is not defined at LoginComponent.ngAfterVie ...

Extending an interface in TypeScript to include an Array

Can I implement a parent interface in Angular 4? export interface Devices extends Array<Device> { } The error 'Class 'DevicesModel' incorrectly implements interface 'Devices'. Property 'includes' is missing in typ ...

Troubleshooting issue with problemMatcher in VSCode TypeScript compiler not functioning

I am looking for a problem matcher that can detect two types of issues: compilation problems related to TypeScript issues flagged by tslint This feature seems to be causing trouble in one of my projects, although it functions properly in others. Below i ...