Redux and NextJS 13 - redux

I am trying to build NextJs app with 13th version of next and redux.
I found the way to pass redux provider in app, but I still don't understand next thing:
How can I use "createAsyncThunk" actions or RTK query with "getStaticProps" and another next functions for fetching data in nextJS 13 and app folder?

getServerSideProps and getStaticProps run on the server so they do not have any relation with your components and your hooks, so there is no way that they have access to the redux provider
but since getServerSideProps runs on every request you can use the request the pass data to it. one solution is to pass data in the url.
let suppose that you have page A with getServerSideProps you can call it like this :
const router = useRouter();
router.push({
pathname: '/url_of_page_A',
query: {
data: JSON.stringify( { a: 'value', b: 'another value'} ) ;
},
});
Now in your page A inside getServerSideProps you can access data via context query
export async function getServerSideProps(context) {
const data = JSON.parse(context.query.data);
}

Related

Detecting new user signup in [...nextauth].js

I'm building an app with NextAuth's email provider as the sole means of user registration and login.
In local development everything worked fine, but when deploying the app to Vercel I keep getting Unhandled Promise Rejection errors from Mongo, so I decided to switch to NextAuth's unstable_getServerSession and everything is running very smoothly now.
Before making the switch I used an extra parameter to communicate whether the user was just logging in or newly signing up. Based on this, I sent different emails (a welcome email with login link vs. a shorter message with just the login link).
Here is how the [...nextauth].js file looked before:
export default async function auth(req, res) {
const signup = req.body.signup || false
return await NextAuth(req, res, {
adapter: MongoDBAdapter(clientPromise),
...
providers: [
EmailProvider({
...
sendVerificationRequest(server) {
customLogin(
server.identifier,
server.url,
server.provider, // passing the above data for email content
signup // custom parameter to decide which email to send
)
}
})
],
...
})
}
I adjusted the code sample from the documentation, but wasn't able to pass a custom parameter to it.
Here is my new code:
export const authOptions = {
adapter: MongoDBAdapter(promise),
...
providers: [
EmailProvider({
...
sendVerificationRequest(server) {
customLogin(
server.identifier,
server.url,
server.provider,
)
}
})
],
...
}
export default NextAuth(authOptions)
The customLogin function doesn't do anything except construction the different email options.
Among the things I have tried are wrapping authOptions in a handler function with req and res, setting up a separate API route, and passing parameters to the NextAuth function, but none of those worked.
Any advise on how to implement a custom parameter here would be highly appreciated.

getStaticProps in dynamic routes in Next.js

I use getStaticProps in a Next.js page.
export const getStaticProps = wrapper.getStaticProps(async ({ store }) => {
store.dispatch(getInfoRequest());
store.dispatch(END);
await store.sagaTask.toPromise()
});
This is a dynamic route.
An when I refresh the page I get:
Error: getStaticPaths is required for dynamic SSG pages and is missing for '/dates/[[...info]]'.
Read more: https://err.sh/next.js/invalid-getstaticpaths-value
Why does this error happen?
It looks like you've forgotten to add getStaticPaths function to your page. Both are required when statically-generating pages for dynamic routes.
Since dynamic routes include parameters that could be anything, Next.js needs to know what concrete paths to generate at build time. This is why you need to export getStaticPaths which should include in its return value a list of string paths with the placeholders replaced with real values.
So, for instance, if your dynamic route is /user/[id], then getStaticPaths might return:
{
paths: [
'/user/1',
'/user/2',
'/user/3'
],
fallback: true
}
You may want to generate these paths dynamically at build time, which you can totally do within getStaticPaths. So, given you've elsewhere created a function called getUsers, it might look like this:
export async function getStaticPaths() {
const users = getUsers();
return {
paths: users.map((u) => `/user/${u.id}`),
fallback: true
}
}
For more information see the documentation.

Is There Any Way to Pass Both ID and Slug from getStaticPaths to getStaticProps [nextjs]

I want to set my URL's as slugs in my next.js app, but also need to pass the itemID to getStaticProps in order to get the data I need from my API.
How can I pass both ID and slug from getStaticPaths to getStaticProps rather than one or the other?
export async function getStaticPaths() {
const paths = items.map(item => (
{ params: { id: item.itemID }}
))
return {paths, fallback: false}
}
I was hoping to do something like this:
const paths = items.map(item => ({
params: {
id: item.itemID,
title: item.description
}
}))
I believe you can find the answer to your question in this blog example from Next.js. They call getStaticPaths() first to get a list of all paths, and then pass that information over to getStaticProps() to get data for each of the paths. Since the data is generated at build time, I believe Nextjs gets all your pages built and ready to serve in one go.

What is PERFORM_ACTION action type inside redux?

Inside my Redux store I recently started getting PERFORM_ACTION actions, which wrap my actual actions as follows:
{
type: PERFORM_ACTION,
action: {
type: REAL_ACTION,
payload: 123
}
}
I was not able to find any answer to this pattern neither in the documentations, nor in Google. The only suggestions that Google included were just references to this type of action without any explanation of what is it and why does it appear in applications.
So, what is this action?
redux dev tool extension wrap your actions with it's own action, what you can do is change the order of the middlewares load,
const store = createStore(
rootReducer,
compose(
applyMiddleware(
/* ---- middlewares ---- */
),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
)
);
if you place the the redux devtools middleware before your middlewares, you will get the warped action.

How to get access to native Firebase object when using angularfire2?

I'm using AngularFire2 (2.0.0-beta.2) incombination with angular2 (2.0.0-rc.4). I'd like to get access to the native firebase object (not the AngularFire root object) from Angularfire2.
Within my component, I want to make calls like:
firebase.auth().currentUser.updateEmail("user#example.com")
where firebase is the native firebase object, like that you get from the fragment below:
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase.js"></script>
<script>
// Initialize Firebase
// TODO: Replace with your project's customized code snippet
var config = {
apiKey: "apiKey",
authDomain: "projectId.firebaseapp.com",
databaseURL: "https://databaseName.firebaseio.com",
storageBucket: "bucket.appspot.com",
};
firebase.initializeApp(config);
</script>
But I don't understand how to setup my angular2 component so that the firebase object is visible within it. Probably a very simple problem to solve, but I don't know how to solve -- I'm not an angular2 expert. I was hoping there would be and AngularFire api to get the object, but there is not.
Also, the reason that I'm trying to do this is that I don't think the angularfire2 api's are complete yet (thats understandable as its still in beta) and I'm trying to work around this. For example I want to update the users email address or password, or send them the forgotten password email. None of this functionality seems to exist yet in AngularFire2, so I'm trying to implement using the native Firebase object.
If you're reading this in September 2016 onwards, this approach might sound good to you.
See the code for superior understanding:
import { Component, Inject } from '#angular/core';
import { AngularFire, FirebaseApp } from 'angularfire2';
#Component({
templateUrl: 'app/auth/resetpassword.component.html'
})
export class ResetpassComponent {
public auth: any;
constructor(private af: AngularFire, #Inject(FirebaseApp) firebaseApp: any) {
this.auth = firebaseApp.auth()
console.log(this.auth);
}
// formData.value.email = 'your#email.com';
onSubmit(formData) {
if(formData.valid) {
console.log('Sending email verification');
this.auth.sendPasswordResetEmail(formData.value.email)
.then( (response) => {
console.log('Sent successfully');
})
.catch( (error) => {
console.log(error);
})
}
}
}
In English:
Import Inject and FirebaseApp
Make available in your component
Start using all the native javascript SDK functions and methods, such as sendPasswordResetEmail()
Doing a auth. doesn't autocomplete with the available methods and functions, so you might need the docs close to you, such as this: https://firebase.google.com/docs/auth/web/manage-users
Any thanks? Give to #cartant : https://stackoverflow.com/a/39069813/1757321
I'm going to try and answer my own question. Let me first say that I'm sure my answer is not the most elegant solution, I'm not yet a javascript/typescript/angular expert. But my answer does work -- even if I don't completely understand.
I used angular-cli to setup my project which is based on angular2 and the latest firebase. Apparently when you use this to setup your project there is a global object created with the name "firebase" in existence. One way to make it visible within your angular 2 component is to put this declaration at the global level in you component (right after the import statements and before your class declaration).
declare var firebase : any;
After you do this the global firebase object is available for use in your component.
RanchoSoftware's solution did not work for me, i used
import {AngularFireModule} from "angularfire2";
import *as firebase from 'firebase';
within the imports in the app.module.ts file
found here:
https://github.com/angular/angularfire2/issues/445

Resources