#Router not pushing to new page inside .then()

1 messages · Page 1 of 1 (latest)

unborn linden
#

const userLeaderboardEntry = addLeaderboardEntryToGame({
gameId: game!._id,
username: username,
round_1: BigInt(allScores[0]),
round_1_distance: BigInt(allDistances[0]),
round_2: BigInt(allScores[1]),
round_2_distance: BigInt(allDistances[1]),
round_3: BigInt(allScores[2]),
round_3_distance: BigInt(allDistances[2]),
round_4: BigInt(allScores[3]),
round_4_distance: BigInt(allDistances[3]),
round_5: BigInt(allScores[4]),
round_5_distance: BigInt(allDistances[4]),
totalTimeTaken: BigInt(0)
}).then(leaderboardEntry => {
console.log("Leaderboard entry added:", leaderboardEntry);
router.push(/results/${leaderboardEntry});
console.log("Sent to:", leaderboardEntry);
});

This is not working even though console.log is correctly printing the id

torn quailBOT
#

Hi @unborn linden. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Based on the information provided in the knowledge sources, there are a few potential reasons why the router.push() might not be working as expected inside the .then() block. Let me explain the possible issues and suggest solutions:

  1. Server Action Interference:
    If addLeaderboardEntryToGame is a server action, it might be interfering with the client-side navigation. According to a GitHub issue comment (https://github.com/vercel/next.js/issues/65287), this is due to action queuing and is expected behavior. The action might return a revalidate payload, so the client needs to wait.

Solution: Instead of using router.push(), it's recommended to use redirect() or revalidatePath() in server actions. Here's an example of how you could modify your code:

'use server'

import { redirect } from 'next/navigation'

// ... your existing code ...

.then(leaderboardEntry => {
    console.log("Leaderboard entry added:", leaderboardEntry);
    redirect(`/results/${leaderboardEntry}`);
});

This approach is recommended in the Next.js documentation on redirecting after server actions (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#redirecting).

  1. ESLint Rule Interference:
    If you have the ESLint rule no-floating-promises enabled, it might be causing issues with router.push(). As mentioned in the Next.js documentation on potential ESLint errors (https://nextjs.org/docs/pages/api-reference/functions/use-router#potential-eslint-errors), you can handle this by either disabling the rule or using void on the Promise.

Solution:

// Disable ESLint for this line
// eslint-disable-next-line no-floating-promises
router.push(`/results/${leaderboardEntry}`);

// Or use void
void router.push(`/results/${leaderboardEntry}`);
#
  1. Dynamic Routing Issue:
    There's a possibility that your routing structure is causing confusion for Next.js. As mentioned in a GitHub issue comment (https://github.com/vercel/next.js/issues/45000), if you have dynamic routes, Next.js might misinterpret the navigation.

Solution: Try specifying both the href and as parameters in router.push():

router.push({
    pathname: '/results/[id]',
    query: { id: leaderboardEntry },
}, `/results/${leaderboardEntry}`);

If none of these solutions work, it might be helpful to check your Next.js and React versions, as there have been changes in routing behavior across different versions. Also, ensure that you're using the correct import for useRouter() based on whether you're using the Pages Router or the App Router.

Remember to test these solutions in your specific context, as the exact behavior can depend on your project's configuration and the full implementation details.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@unborn linden Kapa.ai is still learning and improving, please let me know how I did by reacting below.

unborn linden
#

@torn quail when I try you solution #1, i get this error:

Unhandled Runtime Error
Error: NEXT_REDIRECT

Source
app/(main)/game/_context/GameContext.tsx (142:26) @ eval

140 | }).then(leaderboardEntry => {
141 | console.log("Leaderboard entry added:", leaderboardEntry);

142 | redirect(/results/${leaderboardEntry});
| ^
143 | });
144 | } else {
145 | setCurrentRound(currentRound + 1);

torn quailBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

Thank you for providing that additional information. The error you're encountering is related to how redirect() functions in Next.js, particularly within server actions and try/catch blocks. Let me explain the issue and provide a solution based on the knowledge sources.

The NEXT_REDIRECT error you're seeing is actually an internal Next.js mechanism for handling redirects. According to a GitHub issue comment (https://github.com/vercel/next.js/issues/59930), this is expected behavior:

Because APIs such as redirect and notFound interrupt program execution by throwing exceptions that Next.js can handle.

The problem occurs because the redirect() function is being called inside a .then() block, which is essentially a try/catch structure. To resolve this, we need to adjust where and how we use the redirect() function.

Here's a suggested solution:

  1. Move the redirect() call outside of the .then() block.
  2. Use a state or ref to store the leaderboard entry ID.
  3. Use the useEffect hook to perform the redirect after the state has been updated.

Here's how you could modify your code:

"use client";

import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';

// ... other imports and code ...

const [leaderboardEntryId, setLeaderboardEntryId] = useState(null);
const router = useRouter();

useEffect(() => {
  if (leaderboardEntryId) {
    router.push(`/results/${leaderboardEntryId}`);
  }
}, [leaderboardEntryId, router]);

// ... in your component logic ...

const userLeaderboardEntry = addLeaderboardEntryToGame({
  // ... your existing parameters ...
}).then(leaderboardEntry => {
  console.log("Leaderboard entry added:", leaderboardEntry);
  setLeaderboardEntryId(leaderboardEntry);
});
#

This approach avoids the issue of redirect() throwing an error inside a try/catch or .then() block. Instead, it uses the client-side router.push() method to perform the navigation after the server action has completed.

As mentioned in the Next.js documentation (https://nextjs.org/docs/app/api-reference/functions/redirect#example), the redirect() function is designed to terminate the rendering of the current route segment. By moving the navigation logic to the client side, we avoid this termination behavior and allow for a smoother transition.

Remember to ensure that your component is a Client Component (use the "use client" directive at the top of your file) when using hooks like useState, useEffect, and useRouter.

If you're still encountering issues, it might be helpful to review your overall routing structure and ensure that you're using the appropriate routing methods for your Next.js version and project setup.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: