MAY 15, 2019

A while ago we had the need to grab the App window variable (exposed by CefSharp) and we were extending the Window interface to do that. There seems to be a better way to get variables that are define in the Window environment.

I learned this from this link An advanced guide on how to setup a React and PHP.

If you are defining a variable or object you want to read from React (like in CefSharp, o directly in the HTML like in the screenshot)

// inside of your app entry HTML file's header
<script>
var myApp = {
  user: "Name",
  logged: true
}
</script>

You can do a declare module 'myApp' in index.d.ts, then add the myApp variable as a external library in Webpack's config file

externals: {
  myApp: `myApp`,
},

Then you can import as if it was a module in TypeScript (or JavaScript files) with React

import myApp from 'myApp';

And you can even use TypeScript destructuring technique to get internal properties directly

const { user: { name, email}, logged } = myApp;

FEBRUARY 25, 2019

In trying to export my React's Redux store from index.tsx to be used somewhere else outside of the React application, I was getting an Invariant Violation: Target container is not a DOM element error while running Jest tests (with Enzyme and Webpack) in the App component (App.tsx).

I found a solution to this error for my use case, which was using the same Redux store React is using outside of React.

The error

The initial code that didn't work when testing React looked like this.

// index.tsx

import * as React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { applyMiddleware, compose, createStore } from "redux";
import App from "./components/App";
import { rootReducer } from "./store/reducers";
import { initialState } from "./store/state";

const middlewares = [];

export const store = createStore(
    rootReducer,
    initialState,
    compose(applyMiddleware(...middlewares)),
);

render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById("root"),
);

The solution

Separate the Redux store logic into a new file named store.ts, then create a default export (to be used by index.tsx, i.e., the React application) and a non-default export with export const store (to be used from non-React classes), as follows.

// store.ts

import { applyMiddleware, compose, createStore } from "redux";
import logger from "redux-logger";
import { rootReducer } from "./store/reducers";
import { initialState } from "./store/state";

const middlewares = [];

export const store = createStore(
    rootReducer,
    initialState,
    compose(applyMiddleware(...middlewares)),
);

export default store;
// updated index.tsx

import * as React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import store from "./store";

render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById("root"),
);

Using the Redux store in non-React classes

// MyClass.ts

import { store } from "./store"; // store.ts

export default class MyClass {
  handleClick() {
    store.dispatch({ ...new SomeAction() });
  }
}

The default export

A small note before you go. Here is how to use the default and the non-default exports.

  • default export store; is used with import store from "./store";
  • export const store = ... is used with import { store } from "./store";

If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.

NOVEMBER 14, 2018

for...of1

const numbers = [1, 3, 100, 24];
for (const item of numbers) {
  console.log(item); // 1, 3, 100, 24
}

AUGUST 28, 2018

In TypeScript, as in other languages, Array.map allows you to apply a function to each of the items on a list or array. You can either pass an existing function which will take each of the items as its input parameter (say, the existing Math.sqrt function, or one that you define).

let list = [0, 1, 2, 3]; // [0, 1, 2, 3]
list.map(Math.sqrt); // [ 0, 1, 1.414.., 1.732.. ]

Or you can also define a lambda function on-the-go.

let list = [0, 1, 2, 3]; // [0, 1, 2, 3]
list.map((value, key, all) => {
  list[key] = value * 2;
}); // [ 0, 2, 4, 6]

APRIL 5, 2018

To import JSON into your TypeScript code, you need to add the following code to a typings file (a file with a name like *.d.ts, say, json.d.ts—but it does not necessarily need to say json)1.

// This will allow you to load `.json` files from disk

declare module "*.json"
{ const value: any;
  export default value;
}

// This will allow you to load JSON from remote URL responses

declare module "json!*"
{ const value: any;
  export default value;
}

After doing this, you can do the following in TypeScript.

import * as graph from './data/graph.json';
import data from "json!http://foo.com/data_returns_json_response/";

You can then use graph and data as JSON objects in your TypeScript code.


I used this code to load a Dynamo JSON graph into TypeScript — just change the .dyn extension to .json and it will work with this code.

Want to see older publications? Visit the archive.

Listen to my Podcast.