Open adaboina21 opened 4 years ago
when i am running in node environment getting this error ReferenceError: navigator is not defined.
This library is designed for in-browser usage in the first place. What are you trying to achieve using it in node env?
yes, i am using this in angular js but still same issue
The reason it throws an error is that there is no navigator
object in global scope in node env, which this library essentially relies on. Once again, this library is for usage in browser, not in the node env.
How does it fail while using angular?
@RusinovAnton because he is using angular SSR I guess,
you can use the library using a script tag https://raw.githubusercontent.com/biggora/device-uuid/master/lib/device-uuid.min.js
the problem happens because DeviceUUID function is IIFE so it will be invoked directly when you importe it
the final code after adding the script tag should be like this (window as any).DeviceUUID()
with that, another issue will appear tells that window not defined
const $window = (() => { try { return window; } catch (error) { return {} as Window; } })();
you can mock the window to avoid it
@RusinovAnton i have this problem too . when run project in ssr with command : npm run dev:ssr get same error:
return new DeviceUUID(navigator.userAgent);
^
ReferenceError: navigator is not defined
im using a mock browser , in server.ts file :
const MockBrowser = require('mock-browser').mocks.MockBrowser;
const mock = new MockBrowser();
global['navigator'] = mock.getNavigator();
global['window'] = mock.getWindow();
global['document'] = mock.getDocument();
@ezzabuzaid What do you mean by using tag script? I don't know where to put this tag
thanks
@mkhalesi
It's been a while and I don't exactly remember what I've done to make it work, my bad didn't provide much information back then and I am no longer working on that project.
I would advise to lazy load the script and run it only in browser env
constructor( @Inject(PLATFORM_ID) platformId) {
const isBrowser = isPlatformBrowser(platformId);
// Lazy load "device-uuid"
}
@ezzabuzaid thanks for response
but i checked isPlatformBrowser anywhere project use 'deviceuuid'
const deviceId = isPlatformBrowser(this.platfromId) ? new DeviceUUID().get() : ' ' ;
@biggora
@mkhalesi This won't work
the issue is when you import the library, the navigator will be immediately be used regardless of where you use DeviceUUID
. that's why you have to lazy load it.
@ezzabuzaid Thank you very much for Help i worked based on your tips like this:
if (isPlatformBrowser(this.platformId)) {
import('device-uuid').then( module => {
const deviceId = new module.DeviceUUID().get() ;
});
}
and worked properly thanks :)
@ezzabuzaid can you please guide me to run the same in react js ssr?
@sankar2389 Same steps, check if you're in a browser environment, if so then lazy load the library. I don't have much knowledge in react - you can run the import function in componentDidMount
hook as it doesn't run in the server
Solved by calling the library in useEffect.
For next.js, (react) use this code
useEffect(()=>{ import("device-uuid") .then(module=>{ const uuid = new module.DeviceUUID().parse(); const id = new module.DeviceUUID().get(); console.log(uuid, id); })
},[])
resolved this with async await in nextjs/react app
const generateDeviceId = async () => {
try {
const DeviceUUID = await import('device-uuid');
// slicing it to 10 characters. Otherwise you can maintain the original length by omitting the toUppercase, slice and replace methods
const deviceIdInstance = new DeviceUUID.DeviceUUID()
.get()
.toUpperCase()
.slice(0, 11)
.replace(/-/g, '');
return deviceIdInstance;
} catch (error) {
alert(error);
}
};
could you please give some context on it?