Utilizing the power of dojo/text! directly within a TypeScript class

I have encountered examples suggesting the possibility of achieving this, but my attempts have been unsuccessful. Working with Typescript 2.7.2 in our project where numerous extensions of dijit._Widget and dijit._TemplatedMixin are written in JavaScript, we are transitioning towards Typescript gradually. I have defined an interface that extends these two classes (along with others) with a constructor in a d.ts file. This interface is then extended in a class implemented in Typescript using AMD class definition syntax. I am declaring an extension of this class and attempting to utilize dojo/text! to load an HTML template within the extension. The content of form.d.ts is as follows:

/// <reference path="../../../../../../../node_modules/dojo-typings/dojo/1.11/dojo.d.ts" />
/// <reference path="../../../../../../../node_modules/dojo- typings/dijit/1.11/dijit.d.ts" />
/// <reference path="../../../../../../../node_modules/@types/dom.generated.d.ts" />

declare namespace com {
  namespace foo {
    namespace bar {
      namespace web {
        namespace components {
          namespace form {
            interface ModelObjectMainFormView extends dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin, dojo.Evented {
              on(type: string | dojo.ExtensionEvent, func: dojo.EventListener | Function): dojo.WatchHandle;
              emit(type: string | dojo.ExtensionEvent, ...events: any[]): boolean;
            }

            interface ModelObjectFormViewConstructor {
              new (args: Array<any>);
            }

          }
        }
      }
    }
  }
}

Contained in modules.d.ts:

/// <reference path="index.d.ts" />

declare module 'com/foo/bar/web/components/form/ModelObjectMainFormView' {
  type ModelObjectMainFormView = com.foo.bar.web.components.form.ModelObjectMainFormView;
  const ModelObjectMainFormView: com.foo.bar.web.components.form.ModelObjectFormViewConstructor;
  export = ModelObjectMainFormView;
}

declare module "dojo/text!*" {
  var _: string;
  export default _;
}

The AMD declaration for the extension reads as:

import declare = require("dojo/_base/declare");
import ModelObjectMainFormView = require("com/foo/bar/web/components/form/ModelObjectMainFormView");

class TSModelObjectMainFormView {
  inherited: (args: Object) => any;
}

var exp = declare("com.foo.bar.web.components.form.TSModelObjectMainFormView", [ModelObjectMainFormView], new TSModelObjectMainFormView());
export = exp;

Including the attempt at using dojo/text! in the extension code snippet below:

/// <amd-dependency path="dojo/text!com/foo/bar/web/workItems/configuration/forms/templates/ConfigurationWorkItemMainFormView.html" name="template" />
import * as aspect from 'dojo/aspect';
import * as domAttr from 'dojo/dom-attr';
import * as domClass from 'dojo/dom-class';
import * as domConstruct from 'dojo/dom-construct';
import * as lang from 'dojo/_base/lang';
import ModernizationUtil = require('com/foo/bar/rtc/web/util/ModernizationUtil');
import MimeTypes = require('com/foo/bar/web/scm/MimeTypes');
import * as TSModelObjectMainFormView from '../../../components/form/TSModelObjectMainFormView';
// import * as template from "dojo/text!com/foo/bar/web/workItems/configuration/forms/templates/ConfigurationWorkItemMainFormView.html";
let template: string;

export class ConfigurationWorkItemMainFormView extends TSModelObjectMainFormView {
  templateString = template;

  constructor(args?: any) {
    super(args);
  }
}

The use of amd-dependency comes into play due to the failure of importing dojo/text! during runtime when seeking the module, resulting in a "module not found" error. By using amd-dependency, template is explicitly defined as a string within the source, containing the HTML loaded by dojo/text!. The challenge arises because the call to super() in the constructor must precede other lines of code, yet it relies on templateString being set. However, the assignment of templateString occurs after the constructor's return.

Any insights or assistance would be greatly appreciated. Additional information can be provided upon request. Thank you for your help.

Answer №1

After some tinkering, I was able to successfully implement the changes needed for this to function properly: When modifying the AMD declaration of the extension:

class TSModelObjectMainFormView {
  templateString: string;
  inherited: (args: Object) => any;

  constructor(args?: any) {
    if (args && args.templateString) {
      this.templateString = args.templateString;
      this.inherited(arguments);
    }
  }
}

As well as adjusting the Typescript class that extends TSModelObjectMainFormView:

constructor(args: any) {
  super(lang.mixin(args, {templateString: template}));
}

I believe there may be a more efficient way to approach this. Any guidance or advice would be greatly appreciated. It appears that the current implementation still relies on amd-dependency, which is considered deprecated.

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

Troubleshooting: Angular add/edit form issue with retrieving data from a Span element within an ngFor loop

I am currently working on an add/edit screen that requires submitting a list, among other data. The user will need to check 2-3 checkboxes for this specific data, and the saved record will have multiple options mapped. Here is what the HTML looks like: &l ...

The TypeOrm many-to-one relationship with a multiple column join is giving an error: The column mentioned in the reference, <column name>, was not found in the entity <entity name>

I have an entity called A with a composite primary key, and another entity called B that has foreign keys referencing both columns of entity A. I am currently attempting to establish a many-to-one relationship between entity B (many) and entity A (one). U ...

Distributing utility functions universally throughout the entire React application

Is there a way to create global functions in React that can be imported into one file and shared across all pages? Currently, I have to import helper.tsx into each individual file where I want to use them. For example, the helper.tsx file exports functio ...

strictNullChecks and the dissemination of null values

Considering implementing the strictNullChecks flag in a large code base presents some challenges. While it is undeniably a valuable tool, the abundance of null types in interface definitions may be impacting the code's readability. This is particularl ...

Example of TypeScript Ambient Namespace Usage

The Namespaces chapter provides an example involving D3.d.ts that I find puzzling. Here is the complete example: declare namespace D3 { export interface Selectors { select: { (selector: string): Selection; (element: ...

Configuring Typescript target and library to utilize Promise.allSettled on outdated web browsers

I am currently using TypeScript version 4.3.5 and Node.js version 14.18.1 in my project. The code I am working on is compiled to target both old and new browsers by setting target=es5 in the tsconfig file. I make use of both Promise.all and Promise.allSett ...

Understanding type inference in TypeScript

I'm attempting to grasp the concept of inferring generics in Typescript, but I can't seem to figure out where I'm going wrong. Although my concrete example is too large to include here, I've provided a link to a small TypeScript playgro ...

Ways to access an observable's value without causing a new emit event

Is there a way to retrieve the value of an observable without causing it to emit again? I need this value for an ngClass expression. I attempted to use the tap operator within the pipe to access the values in switchMap, but the value is not being logged. ...

Ways to restrict data types within function parameters

Can you validate types of one argument based on another argument in functions? Consider this example: interface Data { id?: number; name?: string; } let data : Data = {}; // I am unsure how to make the "value" argument strict function update(field : ...

Recursive array generation

Given an array 'featureList', the goal is to create a new array 'newArray' based on a specific ID. For example, for ID 5, the newArray would be ['MotherBoard','Antenna','Receiver'], where Receiver correspon ...

`Is there a way to effectively test an @Input component in Angular?`

Despite multiple successful attempts in the past, I am facing some difficulty getting this to function properly. Within my component, I have an input @Input data: Data, which is used in my template to conditionally display certain content. Oddly enough, du ...

Discovering the JavaScript source file for a package using WebStorm and TypeScript

In my TypeScript project, there is a usage of Express with the following method: response.send('Hello'); I am interested in exploring the implementation of the send() method. However, when I try to navigate to the source code by ctrl+clicking o ...

Utilizing Observable to dynamically bind ngClass in Angular

I currently have a container with the following structure <mat-sidenav-container [ngClass]="{'sidepanel-opened': ((isSidePanelVisible$ | async) as isSidePanelVisible) == true }"> </mat-sidenav-container> I am trying to u ...

Lazy loading in Angular allows you to navigate directly to a certain feature component

I'm currently working on implementing lazy loading in Angular 6, and I want to include links on my main homepage that direct users to specific feature components. Here is the hierarchy of my project: app.module.ts |__homepage.component.ts |__options ...

Leveraging default values in generic implementations

Imagine a scenario where the following code is present: type QueryResult<ResultType = string, ErrorType = string> = { result: ResultType, } | { errors: ErrorType, } So, if I want to initialize my result, I can proceed like this: const myResult: ...

How can a secondary property type be determined by the key utilized in another property?

My goal is to develop a filter type that uses the primary object type to specify a set of keys for "field" and then assigns the appropriate type to the "value". However, I have encountered challenges in achieving this as the best outcome I could attain w ...

Having trouble getting Typescript code to function properly when using commonjs style require statements

I am completely new to Typescript, Node.js, and Express. Following the instructions outlined in this tutorial (https://www.digitalocean.com/community/tutorials/setting-up-a-node-project-with-typescript), I set up my project exactly as described there. The ...

Construct a string by combining the elements of a multi-dimensional array of children, organized into grouped

My task involves manipulating a complex, deeply nested array of nodes to create a specific query string structure. The desired format for the query string is as follows: (FULL_NAME="x" AND NOT(AGE="30" OR AGE="40" AND (ADDRESS ...

Why isn't the unit test passing when it clearly should be?

I am encountering an issue with testing a simple function that I have created. Despite the fact that the function works correctly in practice, it is not being tested properly... Explanation of how my function operates (While it functions as intended, the ...

Exciting Dynamic Text Animation in React using styled components

I came across this cool jumping text effect on https://web.dev/patterns/animation/animated-words/ and wanted to incorporate it into my app. However, when I tried implementing the component in React, I encountered some issues. I created a styled component a ...