Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No Typescript compatibility, and 'window is not defined' error on Next.js #72

Open
0sssama opened this issue Jul 1, 2022 · 7 comments

Comments

@0sssama
Copy link

0sssama commented Jul 1, 2022

I'm trying to use svgMap with Next.js and Typescript and I feel like I'm doing something wrong.

First of all, I can't find any '@types/svgmap' package when I try to install one, so I just need to force Typescript to ignore this.

Secondly, I am using the library as it is documented, but I get a 'window is not defined' error when I run the code. I have created a div element with the "svgMap" id with it as follows:
<div className="map-container w-full" id="svgMap"></div>

I imported the library, with its css.

// @ts-ignore
import svgMap from "svgmap";
import "svgmap/dist/svgMap.min.css"

and created a new svgMap when the component is mounted. I've also made sure that it's only run if 'window' is defined. Here's the code:

useEffect(() => {
    new svgMap({
      targetElementID: "svgMap",
      data: {
        data: {
          gdp: {
            name: "GDP per capita",
            format: "{0} USD",
            thousandSeparator: ",",
            thresholdMax: 50000,
            thresholdMin: 1000,
          },
          change: {
            name: "Change to year before",
            format: "{0} %",
          },
        },
        applyData: "gdp",
        values: {
          AF: { gdp: 587, change: 4.73 },
          AL: { gdp: 4583, change: 11.09 },
          DZ: { gdp: 4293, change: 10.01 },
          // ...
        },
      },
    });
  }, []);

That is an example map data that's stated in the documentation of the library, and as I said when I run it I get this:
image

Am I using the library in a wrong way? or Is it not compatible with React yet?

@StephanWagner
Copy link
Owner

Hmm, I actually haven't testet it with react yet. svgMap doesn't use typescript.

It sould work though as long as the DOM element is present at the time of initializing. There is an ES6 Demo in the demo folder which works fine.

@nikhilnxvverma1
Copy link

Any update on this, I like the library but I think its missing server side rendering support. This is most likely because merely importing the code is executing off some browser dependent code(like window)

@StephanWagner
Copy link
Owner

I just added a React demo. You can download v2.10.1 and check it out. It seems to work just fine.

To boot it up yourself:
cd demo/react/app/
npm install
npm run start

I'm initializing svgMap once the DOM is ready:

// React
import React, { Component } from 'react';
import './App.css';

// svgMap
import svgMap from 'svgmap';
import 'svgmap/dist/svgMap.min.css';

class App extends Component {

  componentDidMount() {
    if (!this.svgMap) {

      var mySvgMap = new svgMap({
        targetElementID: 'svgMap',
        data: {
          data: {
            gdp: {
              name: 'GDP per capita',
              format: '{0} USD',
              thousandSeparator: ',',
              thresholdMax: 50000,
              thresholdMin: 1000
            },
            change: {
              name: 'Change to year before',
              format: '{0} %'
            }
          },
          applyData: 'gdp',
          values: {
            AF: { gdp: 587, change: 4.73 },
            AL: { gdp: 4583, change: 11.09 },
            DZ: { gdp: 4293, change: 10.01 }
            // ...
          }
        }
      });

      this.svgMap = mySvgMap;
    }
  }

  render() {
    return (
      <div className='app'>
        <h1>svgMap React demo</h1>
        <div id='svgMap'></div>
      </div>
    );
  }
}

export default App;

@0sssama
Copy link
Author

0sssama commented Jul 11, 2022

Hey @nikhilnxvverma1

I solved the issue with svgMap and Next.js' SSR by importing the library only in the client side.

useEffect(() => {
   const svgMap = require("svgmap")

   new svgMap({
      options...
   })
}, [])

I don't know if this is the most optimal solution, but it seems to work just fine for now.

@nikhilnxvverma1
Copy link

Thanks for the response guys. I am using angular, so the feature of dynamic imports is kinda dicey. Also, I can't use a bare element ID. But I have the element object in my code(via ViewChild). Unfortunately the library doesn't provide the support for using element objects directly. This I feel, can be an easy fix. Thanks.

@StephanWagner
Copy link
Owner

Im working on a complete overhowl and added using elements rather than ids to the TODO list.

In the meantime, would it work if you just add an ID to the element before you initialize the map? That should work as long as the element is in the DOM tree.

E.G.:

elementObject.setAttribute('id', 'my-id');

new svgMap({
  targetElementID: 'my-id'
});

@nikhilnxvverma1
Copy link

Didn't try it, but I believe in Angular's world, using direct DOM ids is discouraged in the first place. Nevertheless, looking forward to your future developments 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants