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

TypeError: Cannot read property 'parentNode' of undefined #36

Closed
JojoDz opened this issue Apr 26, 2022 · 4 comments
Closed

TypeError: Cannot read property 'parentNode' of undefined #36

JojoDz opened this issue Apr 26, 2022 · 4 comments

Comments

@JojoDz
Copy link

JojoDz commented Apr 26, 2022

We're using the speedometer in our app and great thanks for it.

We are unit testing with jest, and when we include the Speedometer in one svelte component, we have the following error :

TypeError: Cannot read property 'parentNode' of undefined 

When we follow the stack it leads to mountGauge :

config = getConfig({
                        PROPS,
                        parentWidth: gaugeDiv.parentNode.clientWidth,
                        parentHeight: gaugeDiv.parentNode.clientHeight
                });

So gaugeDiv is undefined. We've seen the unit tests of svelte-speedometer, and we don't understand why it fails with our tests.

Do you have an idea why gaugeDiv would not be bound ?

As @palerdot suggested, we rendered the speedometer inside a div, but the test still fails.

This is an extract of the Svelte file where we added Speedometer :

<section class='account'>
	<h1>{$_('account.home.title')}</h1>
	{#await userPromise}
		Loading user...
	{:then me}
		<div class='account__user'>
			<p class='account__user__username'><span>{me.firstname}</span> <span>{me.lastname}</span></p>
			<p class='account__user__email'>
				{ $_('account.home.your_email') } <span>{me.email}</span>
			</p>
		</div>
               {#await getUserQuota(me.email)}
			Loading usage...
		{:then quota}
			<div class='account__subscription'>
				{ $_('account.home.your_subscription') }
				<span>
					{$number(price, { style: 'currency', currency })} / {	$_('signup.month')}
					{$_('signup.for')} <span>{humanSize(quota.total, $_('account.home.sizes'))}</span>
				</span>
			</div>
			<div class='account__quota'>
				{ $_('account.home.quota') }
				<span>{humanSize(quota.used, $_('account.home.sizes'))}/{humanSize(quota.total, $_('account.home.sizes'))}
					({$number(quota.used/quota.total, { style: 'percent' })})</span>
			</div>
			**<Speedometer
				height={180}
				maxValue={100}
				value={100*quota.used/quota.total}
				currentValueText={$_('account.volume.title', { values: { userVolumeStorage: $number(quota.used/quota.total, { style: 'percent' }) }})}
				needleColor="#f2ebe3"
				segments={3}
				customSegmentStops={[0, 75, 90, 100]}
				segmentColors={["#00D692", "#FFE032", "#FF504D"]}
			/>**
		{/await}
	{:catch error}
		<p style="color: red">{error.message}</p>
	{/await}
</section>

<section class="account__unsubscribe">
	<div class="account__unsubscribe__content">
		<h1>{$_('account.unsubscribe.title')}</h1>
		<p>{$_('account.unsubscribe.content')}</p>
		<ConfirmButton 
			popupLabel={$_('account.unsubscribe.popover.title')} 
			noLabel={$_('account.unsubscribe.popover.no')} 
			yesLabel={$_('account.unsubscribe.popover.yes')} 
			callback={removeAccount}
			disabled={disabled}
		>
				{$_('account.unsubscribe.button')}
		</ConfirmButton>
		{#if globalMessage}
			<p>
				<Alert type={alertType} content=	{globalMessage} callback={() => globalMessage 	= null}/>
			</p>
		{/if}
	</div>
</section>

Here is the sample test code where we get the TypeError message :

test('click yes-option button in popper proceeds to unsubscription', async () => {
		const {getByText} = render(unsubscribe)
		const buttonYes = getByText('Yes')
		await fireEvent.click(getByText('Cancel mandate and remove user'))
		await waitFor(() => {
			expect(buttonYes).toBeInTheDocument()
		})
		await fireEvent.click(buttonYes)

		await waitFor(()=> {
			expect(getByText('Account removed')).toBeInTheDocument()
		})
		expect(getByText('Cancel mandate and remove user')).toBeDisabled()
	})

The complete error message :

Unsubscribe › click yes-option button in popper proceeds to unsubscription   
                                                                             
TypeError: Cannot read property 'parentNode' of undefined                    
                                                                             
  at mountGauge (node_modules/svelte-speedometer/dist/index.js:6621:30)      
  at node_modules/svelte-speedometer/dist/index.js:6643:7                    
  at run (node_modules/svelte/internal/index.js:22:12)
      at Array.map (<anonymous>)
  at node_modules/svelte/internal/index.js:1734:45
  at flush (node_modules/svelte/internal/index.js:1042:17)
  at update (node_modules/svelte/internal/index.js:1380:13)
  at node_modules/svelte/internal/index.js:1387:13

I guess the problem lies in the fact that we are using two components from different libraries on the same Svelte page and both having onMount() parts : Speedometer and our customized Confirm Button (with a popup from the lib PopperJs). But how can I be sure? Do you have any other ideas ?

@palerdot
Copy link
Owner

I don't see an html wrapping around Speedometer.

Please try

<div style="width: 300px; height: 300px"> -> add an enclosing div which is missing in your code sample
   <Speedometer />
</div>

@JojoDz
Copy link
Author

JojoDz commented Apr 27, 2022

I added the missing html wrapping (just above). With your suggestion, I added :

<div class="account__speedometer" style="width: 300px; height: 300px">
				<Speedometer
					height={180}
					maxValue={100}
					value={100*quota.used/quota.total}
					currentValueText={$_('account.volume.title', { values: { userVolumeStorage: $number(quota.used/quota.total, { style: 'percent' }) }})}
					needleColor="#f2ebe3"
					segments={3}
					customSegmentStops={[0, 75, 90, 100]}
					segmentColors={["#00D692", "#FFE032", "#FF504D"]}
				/>
			</div>

But still get the same error message ...

@JojoDz
Copy link
Author

JojoDz commented Apr 27, 2022

After deeper analysis, we found that the problem might come from bind:this.
We were helped by this issue.
It occurs both with gaugeDiv and d3_ref.

We managed to get a green test by adding a delay in mountGauge and updateGauge. So it seems related to bootstrap workflow of Svelte components. Also the test works in Webstorm.

@palerdot
Copy link
Owner

palerdot commented Apr 27, 2022

Glad things are working for you. I'm closing this issue as it is not related to the library.

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

2 participants