Skip to content

clearNuxtState should take default value instead of undefined #32117

@Harm-Nullix

Description

@Harm-Nullix

Environment

  • Operating System: Darwin
  • Node Version: v20.16.0
  • Nuxt Version: 3.16.2
  • CLI Version: 3.24.1
  • Nitro Version: 2.11.8
  • Package Manager: yarn@4.5.0
  • Builder: -
  • User Config: ssr, devtools, compatibilityDate, app, css, build, sourcemap, vite, serverDir, rootDir, srcDir, dir, components, modules, imports, googleFonts, i18n, lodash, devServer, nitro, ignore, routeRules, macros, security, runtimeConfig, experimental
  • Runtime Modules: nuxt-lodash@2.5.3, @vue-macros/nuxt@1.9.37, @nuxtjs/google-fonts@3.2.0, @vueuse/nuxt@13.0.0, @nuxtjs/i18n@9.4.0, nuxt-security@2.2.0, ()
  • Build Modules: -

Reproduction

https://codesandbox.io/p/devbox/laughing-glade-tg2xkn?file=%2Fapp.vue%3A6%2C8

Describe the bug

When you clear the state it gets set to undefined.
Following on the Nuxt 4 migration guide, this should default back to the value it was set to as default. If a user would like to have a undefined state, that should be the default.

https://nuxt.com/docs/getting-started/upgrade#default-data-and-error-values-in-useasyncdata-and-usefetch

In issue #21293 Daniel even mentioned it should have the same API:
#21293 (comment)

In the MR it is visible that the implementation just makes the value undefined: https://github.com/nuxt/nuxt/pull/21409/files#diff-916bd663085bf0545a35adb6fdb951702200d259e2185df08579d96ada525853R54

And the function did not change on the main branch yet either:
https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/state.ts#L58

Additional context

A use case I have right now is a user that logs in.
After login, we set a state to ping user activity.
When logout triggers, clearNuxtState is triggered.
That sets the userActivity state to undefined.
Then when a user tries to log in again, the state is broken.

The only work arround that I can think of is resetting the whole page, or explicitly set the value of all useState objects to a default value again instead of using this function.

I'll add one of the files, the one mentioned above as an extra example

import {useIdle} from '@vueuse/core'


export const useUserActivity = () => {
  const activityState = useState('userActivity', () => ({
    timeoutPID: 0,
    isPaused: false,
  }))
  let hasLoop = false
  const pingInterval = 10 * 1000
  const {idle, lastActive} = useIdle(pingInterval * 2)
  const nuxtApp = useNuxtApp()
  const authService = useAuthState()

  const pingUser = (force: boolean = false) => {
    if (force || authService.hasAuthToken()) {
      nuxtApp.$api(`/server/pingClient?hadUserActivity=${idle.value ? 'false' : 'true'}`).catch()
    }
  }

  //The loop
  const pingUserLoop = () => {
    if (!activityState.value.isPaused) { // CRASHES HERE BECAUSE .value IS UNDEFINED!!
      try {
        activityState.value.timeoutPID = 0
        pingUser()
      } catch (e) {}
    }
    //set interval for next run of loop
    if (!activityState.value.timeoutPID)
      activityState.value.timeoutPID = setTimeout(() => {
        pingUserLoop()
      }, pingInterval)
  }

  //start the loop
  if (!activityState.value.timeoutPID) {
    pingUserLoop()
  }

  return {
    isIdle: idle,
    lastActive,
    pingUser,
    setPause(isPaused: boolean) {
      activityState.value.isPaused = isPaused
    },
    togglePause() {
      activityState.value.isPaused = !activityState.value.isPaused
    },
  }
}

Logs

11:15:02.721 Uncaught TypeError: activityState.value is undefined
    NuxtJS 7
        pingUserLoop
        timeoutPID
        setTimeout handler*pingUserLoop
        useUserActivity
        setup
        createHook
        callWithErrorHandling
useUserActivity.ts:23:9
    NuxtJS 77

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions