Having trouble accessing functions in Typescript when importing JavaScript files, although able to access them in HTML

Recently, I started incorporating TypeScript and React into my company's existing JavaScript code base. It has been a bit of a rollercoaster ride, as I'm sure many can relate to.

After conquering major obstacles such as setting up webpack correctly, configuring and implementing tsconfig files, and organizing the bundling process effectively, I have successfully integrated everything with our current CI pipeline.

However, I am currently facing an issue with importing JavaScript libraries in my TypeScript code. While I understand that this is not best practice, it serves as a temporary solution before transitioning to full TS compliance.

I have a basic component that compiles without any issues:


import * as React from "react";
import * as ReactDOM from "react-dom";
import { Header } from "./components/header";
import * as $C from "./../../fortress.content.js";
import * as $F from "./../../fortress.js"; 

let url : string  = $F.writeUrl("Account", "LoginAjax");

ReactDOM.render(
    <div>
        <div> {url} </div>
    </div>,  
    document.getElementById("body")
);

The $F.writeUrl function allows us to generate a string based on a webconfig file located at the root of the project. Essentially, it takes multiple parameters and returns a formatted string based on them.

However, when I run the transpiled JavaScript in an HTML file:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<div id="body"></div>
<div id="header"></div>
<body> 
    <script src="js/jquery-2.1.4.min.js"></script> 
    <script src="js/react-0.14.3.js"></script>
    <script src="js/react-dom-0.14.3.js"></script> 
    <script src="js/filemanager/filemanager.bundle.js"></script>
    <script src="js/anothermanager/anothermanager.bundle.js"></script>
    <script>  
            console.log("$F: ", $F);
            console.log("$C: ", $C);
    </script>
</body>
</html>

The following errors occur:


Uncaught TypeError: Cannot read property 'bind' of undefined
    at new t (filemanager.bundle.js:1)
    at ReactCompositeComponentWrapper.mountComponent (react.js:5504)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (react.js:12346)
    at Object.mountComponent (react.js:12971)
    at ReactDOMComponent.mountChildren (react.js:11685)
    at ReactDOMComponent._createContentMarkup (react.js:6817)

anothermanager.bundle.js:1 Uncaught ReferenceError: $C is not defined
    at anothermanager.bundle.js:1
    at Object.<anonymous> (anothermanager.bundle.js:1)
    at n (anothermanager.bundle.js:1)
    at Object.<anonymous> (anothermanager.bundle.js:1)
    at n (anothermanager.bundle.js:1)
    at anothermanager.bundle.js:1
    at anothermanager.bundle.js:1
    at ReactDOMComponent.mountComponent (react.js:6705)
    at Object.mountComponent (react.js:12971)
    at ReactCompositeComponentWrapper.mountComponent (react.js:5581)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (react.js:12346)

index.html:17 Uncaught ReferenceError: $F is not defined
    at index.html:17

To resolve this, I attempted to instantiate $C and $F within my TypeScript code:


let test = $F;
let test2 = $C;

This eliminated the above errors and displayed the $F and $C objects in the console log. However, the issue now is that Chrome does not recognize

$F.writeUrl("Account", "LoginAjax")
as a function.

Have I made any mistakes with my imports?

Answer №1

It seems that importing those files into your react bundle may not be necessary. If the files do not export anything with module.exports or export, but instead set up members on the window object to be used later (as was common practice in the past), then you can follow these steps:

1) Include those files as scripts so they are globally accessible. Make sure to include them before any scripts related to react, ensuring they are available when the react code is mounted:

<script src="js/jquery-2.1.4.min.js"></script>
<script src="js/path-to-fortress-content.js"></script>
<script src="js/path-to-fortress.js"></script> 
<script src="js/react-0.14.3.js"></script>
<script src="js/react-dom-0.14.3.js"></script>

2) Now, these files are accessible in your react code. You will need to access them from the window object instead of directly using $F/$C modules in order for your bundler to handle them properly:

let $f: any = (window as any).$F;
let url : string  = $F.writeUrl("Account", "LoginAjax");

Answer №2

[...] incorporating JavaScript libraries into my TypeScript code. Although some may consider it bad practice, I see it as a necessary step before achieving full TS compliance

No need to fret, it's not always frowned upon, especially when in the midst of a transitional phase.

In addition to Sergeon's answer, which addresses the implementation issue, it is worth noting that certain JavaScript libraries do come with typings that allow for their use in TypeScript applications. One example is jQuery:

npm i --saveDev "@types/jquery"

To utilize these typings in a .ts module:

import "jquery";
declare const $: JQueryStatic;

This approach also provides the added benefit of IDE IntelliSense assistance:

https://i.stack.imgur.com/g5yAD.png

If you wish, you can explore and include other libraries from the @types/ repository.

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

Is there a way for me to steer clear of having to rely on the Elvis Operator?

Throughout my journey building my Angular 2 website, I've found the Elvis Operator to be a crucial element that makes everything possible. It seems like every task I undertake involves mastering how to apply it correctly in every instance where data i ...

Utilizing Angular 14 and Typescript to fetch JSON data through the URL property in an HTML

Is there a way to specify a local path to a JSON file in HTML, similar to how the src attribute works for an HTML img tag? Imagine something like this: <my-component data-source="localPath"> Here, localPath would point to a local JSON fil ...

Utilizing Axios for transmitting an authentication token to the server

I'm just starting out with this project Currently, I am developing a Vue application that connects to a WordPress backend and requires user login. To achieve this, I have implemented the Simple JWT-Login plugin. I've successfully managed to send ...

Execute an UPDATE query in PostgreSQL for each item in the array

Imagine a scenario where a cart filled with various grocery items, each having a unique ID, is ready for purchase. When the "purchase" button is clicked, an array containing objects of each item in the cart is sent. The number of items in the cart can vary ...

Is there a performance boost when using queue() and filter() together in jQuery?

I'm currently refactoring some Jquery code and I've heard that chaining can improve performance. Question: Does this also apply to chains involving queue() and filter()? For instance, here is the un-chained version: var self = this, co = ...

Can anyone provide guidance on how to calculate the total sum of a JavaScript array within an asynchronous function?

Currently, I am working with Angularjs Protractor for end-to-end testing and faced an issue while trying to calculate the sum of values in a column. Although I am able to print out each value within the loop successfully, I am struggling to figure out ho ...

Guide on transforming Json information into the preferred layout and iterating through the loop

Currently, I am diving deep into the world of JSON and feeling a bit puzzled by data formats, arrays, objects, and strings. First things first, I'm in need of data structured like this (on a jQuery page). Would this be considered an object or an arra ...

Are the import and export keywords native to webpack or are they specific to JavaScript syntax?

I am pondering whether the import & export aspects are part of the language itself or simply keywords that webpack adds to the language. Thank you. ...

Switch up image transitions using Javascript

I have already completed the css and html structure for my project. However, I am encountering issues with the JavaScript functionality. I really like the image effect on this website: (the blue one). I have attempted to replicate it here: , but have bee ...

Is it possible to access the line number of a node using the TypeScript compiler API?

Is there a method to retrieve the line number of a node besides using node.pos? For example, something like node.lineNumber? ...

Attempting to transfer user information to MongoDB using AngularJS and Node.js

Greetings everyone! I am currently working on a template and trying to develop a backend for it, starting with the registration form. Despite having some kind of connection between my mongodb and my app, data is not being sent to the database. Here is the ...

Step-by-step guide on inserting a div element or hotspot within a 360 panorama image using three.js

As I work on creating a virtual tour using 360 images, I am looking to include hotspots or div elements within the image that can be clicked. How can I store data in my database from the event values such as angle value, event.clientX, and event.clientY wh ...

When utilizing the yo angular-fullstack:endpoint, the message endpoint fails to produce the message.socket.js

Hey there, I've encountered an issue where the yo angular-fullstack endpoint shopPacket is not generating the shopPacket.socket.js file. I attempted to update the yo angular full stack generator, but unfortunately, the problem persists. yo angular-f ...

Is it possible to trigger an AJAX validation only after the jQuery validation plugin has successfully validated the input?

I utilized the jQuery validation plugin for form field validation. The goal now is to send an ajax request only when the fields are deemed valid by the jQuery validation plugin. JavaScript: $(function(){ $("#form").validate({ errorPlacement: ...

AmCharts Axis renderer mistakenly renders an additional grid line

I have successfully created a basic XYChart using amcharts4. To get rid of the grid lines on the x-axis, I changed the stroke opacity for the x-axis grid to 0 using the following code: xAxis.renderer.grid.template.strokeOpacity = 0; Everything was workin ...

Is it possible to temporarily halt animation in react-transition-group while retrieving initial data within components?

I am working with the App component that looks like this: <Route render={( { location } ) => ( <TransitionGroup component="div" className="content"> <CSSTransition key={location.key} className ...

Please provide values in the input box, with each value separated by

I attempted the following code: success: function (result) { for (var i = 0; i < result.d.length; i++) { var emails = new Array(); emails = result.d[i].Emailid; alert(emails); $("#EmailCC").val(emails); ...

Getting the total number of child elements in a web page using Selenium web-driver with Node.js

I've been looking everywhere, but I can't seem to find the answer Here's my HTML code: <form id="search_form_homepage" > ... <div class="search__autocomplete" style="display: block;"> &l ...

Prevent methods from being called in a Typescript class after they have already

I encountered a scenario where I need to exclude certain methods from the return type of a class method once they have been called. Consider a class named Setup with methods step1, step2, and step3. class Setup { step1() { return this; } ...

What is the best way to populate dropdown menus using JavaScript?

I'm facing an issue with my ajax request where I am unable to populate the options of a select tag. This problem is occurring in multiple blocks where the select tag serves the purpose of choosing a type of product. Here is how my select tag looks li ...