Utilizing noty in a Aurelia application with Typescript

I have been attempting to integrate NOTY with my Aurelia/Typescript application. After installing the package via NPM, I used requireJS to bring it into the application.

Despite my efforts, I have not been successful in making it work. I tried two different methods for importing it into the necessary file:


Attempt# 1

import * as Noty from 'noty';

Although this method seemed to create the correct references and there were no build errors, when attempting to use it, I encountered an error stating - "Noty is not a constructor".


Attempt 2

import Noty from 'noty'

This approach raised a complaint about lack of default exported members. I also tried another variation: import { Noty } from 'noty';, but faced similar issues.


Any suggestions on how to successfully implement this would be greatly appreciated. Thank you in advance!


UPDATE#1

I have added the NOTY package reference in the aurelia.json file. https://i.sstatic.net/8Mi9k.png

However, the Noty package still fails to load. https://i.sstatic.net/Fkc1U.png

PS: I have included a link to the NOTY website in case anyone needs to look at the index.d.ts file.

Answer №1

It appears that the issue lies in your requireJS package mapping, which may be incorrectly pointing to the wrong file (such as the index.d.ts file).

I recently checked the 'noty' NPM package and it seems like your requireJS mapping should look something like this:

{ "name": "noty", "path": "../node_modules/noty/lib", "main": "noty.min" }

While TypeScript is concerned with *.d.ts files, requireJS does not deal with TypeScript and only focuses on loading Javascript files into the browser.

By the way, don't worry if you find the complexities of the web platform overwhelming at first glance.

Answer №2

It seems that the noty library uses a named AMD define define('Noty',...) instead of the typical anonymous define. Although it should work, there appears to be a regression caused by my recent PR in the cli-bundler for named AMD modules, or perhaps a new bug specific to named AMD modules.

I will address this regression with an update. The update I made can be found here: https://github.com/aurelia/cli/pull/1084

As a temporary workaround, you can:

  1. Create a new file in your project called patch/noty.js with the following content:
define('noty',['Noty'],function(m){return m;});

This patch creates an alias from 'noty' to 'Noty'.

  1. Add the provided code snippet to aurelia.json after requirejs.
  2. There is also an issue with the default main lib/noty.js:
ERROR [Bundle] Error: An error occurred while trying to read the map file at /Users/huocp/playground/nt/node_modules/noty/lib/es6-promise.map

It is attempting to load es6-promise.map but cannot find the file.

Update: Despite the error message, bundling should continue without interruption.

{
    "name": "vendor-bundle.js",
    "prepend": [
      "node_modules/requirejs/require.js",
// add this line after requirejs
      "patch/noty.js"
    ],
    "dependencies": [
      "aurelia-bootstrapper",
      "aurelia-loader-default",
      "aurelia-pal-browser",
      {
        "name": "aurelia-testing",
        "env": "dev"
      },
      "text",
// If desired, override the noty main path to avoid the es6-promise.map error
      {
        "name": "noty",
        "path": "../node_modules/noty",
        "main": "lib/noty.min"
      }

    ]
}

After making these changes, the import has been tested and confirmed to work properly.

import * as Noty from 'noty';

By the way, if you prefer to avoid using * as, consider utilizing the Microsoft recommended esModuleInterop compiler option. https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html

Answer №3

It seems that the issue you are experiencing is due to NOTY exporting its main functionality in a commonjs way:

module.exports = NOTY;

To import it correctly into your code, you should use the import module syntax like this:

import * as NOTY from 'noty';

This export style is still used by many other libraries that have not switched to the modern ES6 syntax.

Update:

Based on their type definition export: https://github.com/needim/noty/blob/master/index.d.ts#L2

declare module 'noty' {
  exports = Noty;
}

This implies that you should follow your first attempt. However, it is actually shipped differently https://github.com/needim/noty/blob/master/lib/noty.js#L9-L18

(function webpackUniversalModuleDefinition(root, factory) {
  if(typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if(typeof define === 'function' && define.amd)
    ...
  else if(typeof exports === 'object')
    exports["Noty"] = factory();
...

Pay attention to the last part exports["Noty"] = factory(). It seems this is what is being picked up, rather than the first one. This means it equals to named export Noty

The issue you encountered is likely due to this mismatch in the export method. I recommend trying the following approach:

import * as $NOTY from 'noty';

const NOTY = ($NOTY as any).Noty as new (options: $NOTY.OptionsOrSomeThing): $NOTY;

// Proceed with using NOTY in your code
new NOTY();

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

In order to use the serve command, it is necessary to run it within an Angular project. However, if a project definition cannot be located

An error occurred while running the ng serve command: C:\Mysystem\Programs\myfwms>ng serve The serve command needs to be executed within an Angular project, but a project definition could not be found. I encounter this error when ...

There seems to be a mismatch in compatibility between the register() function in react-hook-form and the native input types

Currently, I'm in the midst of a React project that utilizes TypeScript along with react-hook-form. At one point in my code, I am making use of the provided function register(), which should be implemented as follows according to the official document ...

What are the reasons behind my decision not to utilize the correct Card component in React Bootstrap?

I am new to using react. I am attempting to utilize the Card component from bootstrap in the following way: import React from "react"; import { Card, Button } from "@material-ui/core"; const PortfolioSection: React.FC = () => { r ...

In an attempt to successfully retrieve data from a formatted XML API, I am working on making a straightforward API call using JavaScript/TypeScript

I'm currently working on a project that involves calling an API in XML format, but I'm having trouble getting any data to show up. So far, I've attempted to use both JavaScript and TypeScript for making the HTTP request, as well as trying o ...

Incapable of adding a singular string to an array without altering the string's original value

Introducing the edit-customer component, a dialog window designed to receive an injected object from another component and display its properties, such as name and email. Below is the code for this component: HTML <form [formGroup]="editForm"> ...

Using TypeScript to specify precise types for ReactWrapper within the Enzyme library

During my testing process of custom components with jest and enzyme using typescript, I have been creating tests like this: const wrapper = mount(<MyCustomComponent/>); expect(wrapper).toMatchSnapshot(); As mount returns a type of ReactWrapper, I h ...

Unable to extract numerical value from object using Dropdown (Angular 4)

When I retrieve data from an API, everything works smoothly except when I try to bind my JSON option number value into the [value] tag. Here's an example: SUCCESSFUL (data retrieved from API is selected in the option) <select [(ngModel)]="data.fr ...

Most efficient method of retrieving the properties of an object that may possibly contain another object within it

Having the following schema: export type PersonType = { id: string, cnp: string, name: string, surname: string, education: string, email: string, experience: string, homeCounty: string, neighboringCounty1: string, ne ...

What is the most effective way to manage over 100 cases in Typescript without getting overwhelmed?

My aim is to streamline the processing of different types of batches using one program by specifying the batch type in the .env file. The reason for wanting to process all batches with a single program is to avoid configuring a separate Continuous Deploym ...

Error with SwitchMap on ActivatedRoute.paramMap

When I try to run the ngOnInit method of my component, I encountered an error with the following line of code. this.products$ = this.route.paramMap.switchMap((params: ParamMap) => this.getProductsForType(params.get('type'))); The error mes ...

The parameters 'event' and 'payload' do not match in type

Upon running the build command, I encountered a type error that states: Type error: Type '(event: React.FormEvent) => void' is not assignable to type 'FormSubmitHandler'. Types of parameters 'event' and 'payload&apos ...

Angular Dialog Component: Passing and Populating an Array with Mat-Dialog

Here's the situation: I will enter a value in the QTY text field. A Mat dialog will appear, showing how many quantities I have entered. My question is, how can I iterate an object or data in the afterclosed function and populate it to the setItem? Cur ...

There is no corresponding index signature for type 'string' in Type

This is the code snippet I am using as a reference: const MyArray = [ { name: "Alice", age: 15 }, { name: "Bob", age: 23 }, { name: "Eve", age: 38 }, ]; type Name = typeof MyArray[string]["name"]; //throws err ...

Transforming a singular function into a versatile, reusable function with the help of Typescript

In my component, I have a function dedicated to removing duplicate values from an array. const removeDuplicateScenarios = (scenariosList: Scenario[]): Scenario[] => { return _.filter(scenariosList, el => _.filter(scenariosList, e => e.id === el ...

The field 'password' is not found in the data type 'User | undefined'

Howdy everyone, I've encountered an issue stating "Property '_doc' does not exist on type 'User & { _id: ObjectId; }'" in one of my controller documents while trying to fetch a particular user. My backend database is implemented us ...

Utilize React to iterate through an object using the .map

Help needed with fixing an eslint error that says Property 'date' does not exist on type 'never'. The issue seems to be related to data.date. Any suggestions on how to resolve this? import React from 'react' import app from & ...

Generating objects dynamically using Angular 2 framework

My goal is to dynamically create objects and add data using TypeScript. For instance: let data={ "date":"27-5-2017", "name":"John" }; This represents my initial object. Now, I aim to include additional data in it, such as subjects. "Subject1":" ...

The best approach to effectively integrate TypeScript and Fetch is by following the recommended guidelines

Currently, I am in the process of learning React and Typescript simultaneously. On the backend side, I have a server set up with ApiPlatform. For the frontend part, my goal is to utilize fetch to either create or update a Pokemon along with its abilities. ...

The module '@ngmodule/material-carousel' could not be located

Having an issue with Angular 8 where I am encountering an error when trying to import the @ngmodule/material-carousel module. The specific error message is: Cannot find module '@ngmodule/material-carousel' Package.json "private": true, "depen ...

What is preventing the dependency injection of AuthHttp (angular2-jwt) into a component?

UPDATE: Success! Problem Solved After much trial and error, I finally discovered the solution to my issue. It turned out that the problem lied in a simple configuration mistake. To rectify this, I made changes to both my package.json (dependencies section ...