2

Next.js, Graphql, wpgraphql, useMutation hook,material-UI 我尝试构建 WordPress 主题使用 next.js 和 graphql。

我尝试了很多测试,阅读以解决我的错误。

我的域路径:https://blog.rajdeepsingh.dev/graphql


本地服务器:http://localhost:3000/

我的大问题网络错误:JSON 输入意外结束。数据提交时我的注册页面比我的注册组件上显示错误

我将 cors() 库与 express.js 一起使用


我学习

  1. 标题
  2. 证书
  3. 获取选项
  4. 项目清单

单击此处检查错误图像


bundle.esm.js:69 POST https://blog.rajdeepsingh.dev/graphql 500

(anonymous) @ bundle.esm.js:69
Subscription @ Observable.js:197
subscribe @ Observable.js:279
(anonymous) @ bundle.esm.js:864
Subscription @ Observable.js:197
subscribe @ Observable.js:279
(anonymous) @ bundle.esm.js:1001
(anonymous) @ bundle.esm.js:998
step @ tslib.es6.js:100
(anonymous) @ tslib.es6.js:81
(anonymous) @ tslib.es6.js:74
__awaiter @ tslib.es6.js:70
push../node_modules/apollo-client/bundle.esm.js.QueryManager.mutate @ bundle.esm.js:950
push../node_modules/apollo-client/bundle.esm.js.ApolloClient.mutate @ bundle.esm.js:2016
push../node_modules/@apollo/react-hooks/lib/react-hooks.esm.js.MutationData.mutate @ react-hooks.esm.js:453
MutationData._this.runMutation @ react-hooks.esm.js:419
submitFormUser @ signup.js:108
callCallback @ react-dom.development.js:188
invokeGuardedCallbackDev @ react-dom.development.js:237
invokeGuardedCallback @ react-dom.development.js:292
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:306
executeDispatch @ react-dom.development.js:389
executeDispatchesInOrder @ react-dom.development.js:414
executeDispatchesAndRelease @ react-dom.development.js:3278
executeDispatchesAndReleaseTopLevel @ react-dom.development.js:3287
forEachAccumulated @ react-dom.development.js:3259
runEventsInBatch @ react-dom.development.js:3304
runExtractedPluginEventsInBatch @ react-dom.development.js:3514
handleTopLevel @ react-dom.development.js:3558
batchedEventUpdates$1 @ react-dom.development.js:21871
batchedEventUpdates @ react-dom.development.js:795
dispatchEventForLegacyPluginEventSystem @ react-dom.development.js:3568
attemptToDispatchEvent @ react-dom.development.js:4267
dispatchEvent @ react-dom.development.js:4189
unstable_runWithPriority @ scheduler.development.js:653
runWithPriority$1 @ react-dom.development.js:11039
discreteUpdates$1 @ react-dom.development.js:21887
discreteUpdates @ react-dom.development.js:806
dispatchDiscreteEvent @ react-dom.development.js:4168
Show 9 more frames
signup.js:130 undefined " submit Form  test maybe workING 4"
signup.js:131 Error: Network error: Unexpected end of JSON input
    at new ApolloError (bundle.esm.js:63)
    at Object.error (bundle.esm.js:1030)
    at notifySubscription (Observable.js:140)
    at onNotify (Observable.js:179)
    at SubscriptionObserver.error (Observable.js:240)
    at bundle.esm.js:869
    at Set.forEach (<anonymous>)
    at Object.error (bundle.esm.js:869)
    at notifySubscription (Observable.js:140)
    at onNotify (Observable.js:179)
    at SubscriptionObserver.error (Observable.js:240)
    at bundle.esm.js:86 " submit Form  test maybe error 5"

服务器.js

const express = require( 'express' );
const next = require( 'next' );

const port = 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next( { dev } );
const handle = app.getRequestHandler();
var cors = require('cors')
var corsOptions = {
    origin: 'https://blog.rajdeepsingh.dev/',
    optionsSuccessStatus: 200 
    // some legacy browsers (IE11, various SmartTVs) choke on 204
}

    app.prepare()
    .then( () => {
        const server = express();

        server.get( '/read/:slug', ( req, res ) => {
            const postId =  req.params.slug.split( '-' ).pop() 
            const queryParams = { id: postId };
            console.log(queryParams, ' queryParams form server side  ')
            app.render( req, res, '/read', queryParams );
        } );

        server.get( '/comment/comment/:slug', ( req, res ) => {
            const postId =  req.params.slug.split( '-' ).pop()
            const queryParams = { id: postId };
            app.render( req, res, '/comment', queryParams );
        } );
        server.get( '/page/page/:slug', ( req, res ) => {
            console.log(req.params , ' for server here  ')
            const postId = req.params.slug.split( '-' ).pop() 
            const queryParams = { id: postId };
            console.log(queryParams , ' queryParams server here side  ')

            app.render( req, res, '/page', queryParams );
        } );
        

        server.get( '/login', ( req, res ) => {
            return handle( req, res, '/login' );
        } );

        server.post( '/signup',cors(corsOptions), ( req, res ) => {
              //========================
             // show error on signup 
            //==================
            const update= res.json()
            return handle( req, update, '/signup' );
        } );
        server.get( '*', ( req, res ) => {
            return handle( req, res );
        } );

        server.listen( port, ( err ) => {
            if ( err ) {
                throw err;
            }
            console.warn( `Ready on http://localhost:${port}` );
        } );
    } );

阿波罗客户端

 import { ApolloClient } from 'apollo-client';
 import { InMemoryCache , IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
// import withApollo from 'next-with-apollo';
 import { createHttpLink } from 'apollo-link-http';
 import fetch from 'isomorphic-unfetch';
import introspectionQueryResultData from '../fragmentTypes.json';
import { HttpLink } from "apollo-link-http";


// whats  that fragmentMatcher read here >>  https://medium.com/@jacky_ttt/day121-warning-heuristic-fragment-matching-going-on-8208b584cb5e
const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData
});


const cache = new InMemoryCache({ fragmentMatcher });

// const customFetch = (uri, options) => {
//   const { operationName } = JSON.parse(options.body);
//   return fetch(`${uri}/graph/graphql?opname=${operationName}`, options);
// };

// const link = createHttpLink({ fetch: customFetch });
const link = new HttpLink({
  fetch,
  uri: "https://blog.rajdeepsingh.dev/graphql",
  credentials: 'same-origin',
    fetchOptions:{
      mode: 'no-cors',
      method:'POST'
    },
    headers: {
      'Access-Control-Allow-Credentials': true,
      'Content-Type': 'application/json',
     'Access-Control-Allow-Origin': '*',
    } 
});


export const client = new ApolloClient({
  cache,
  link
});

注册组件

import React, { useState } from 'react'
import Layout from '../Component/Layout'
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import Container from '@material-ui/core/Container';
import IconButton from '@material-ui/core/IconButton';
import Input from '@material-ui/core/Input';
import FilledInput from '@material-ui/core/FilledInput';
import OutlinedInput from '@material-ui/core/OutlinedInput';
import InputLabel from '@material-ui/core/InputLabel';
import InputAdornment from '@material-ui/core/InputAdornment';
import FormHelperText from '@material-ui/core/FormHelperText';
import FormControl from '@material-ui/core/FormControl';
import TextField from '@material-ui/core/TextField';
import Visibility from '@material-ui/icons/Visibility';
import VisibilityOff from '@material-ui/icons/VisibilityOff';
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import Link from 'next/link'


import style from '../Component/css/Signup.module.scss'

import gql from 'graphql-tag';
import { useMutation } from '@apollo/react-hooks';


export default function Signup(props) {

    // mutation query with gql
    const getInfoSignup = gql`mutation MyMutation($userData:RegisterUserInput!) {
                __typename
                registerUser(input:$userData) {
                    user {
                      jwtUserSecret
                      username
                      userId
                    }
                    clientMutationId
                  }
            } 
`
    

    const [passward, setPassward] = useState("");
    const [showPassword, setShowPassword] = useState(false);
    const [showconfirmPassword, setShowconfirmPassword] = useState(false);
    const [confirmPassword, setConfirmPassword] = useState("");
    const [matchPassward, setMatchPassward] = useState(false);
    const [checkbox, setCheckbox] = useState(true);
    const [userName, setuserName] = useState("");
    const [gmail, setgmail] = useState("");
    const [displayName, setDisplayName] = useState("");

    // useMutation hook 
    
    const [createUser, { data , error}  ] = useMutation(getInfoSignup);

    // hender error on this way 
    // Read on stackoverFlow https://stackoverflow.com/questions/59465864/handling-errors-with-react-apollo-usemutation-hook#:~:text=Apollo%20Client%20actually%20provides%20four%20different%20ways%20to%20handle%20mutation%20errors%3A&text=Calling%20the%20mutate%20function%20returned,data%20returned%20by%20the%20server.

    //     const [createUser, { data, loading, error }] = useMutation(getInfoSignup, {
//         variables:{
//             userData:{
//                 username: "RajdeepSingh420",
//                 email: "RajdeepSingh420@GMAIL.COM",
//                 password: "RajdeepSingh420",
//                 revokeJwtUserSecret: true,
//                 displayName: "Rajdeep Singh 420",
//                 clientMutationId: "registerUser",
//                 nicename: "RajdeepSingh420",
//                 registered: "true", 
//             }
//         },
//         onError(err) {
//             console.log(err);
//         },
// });
  


   // form  handler function 
     const handleChange = (event) => {
        setPassward( event.target.value )  
      };
    
      const  handleClickShowPassword = () => {
        setShowPassword(!showPassword)
      };

    const confirmHandleChange = (event) => {
        setConfirmPassword( event.target.value)
       
      if( passward === event.target.value ){
        setMatchPassward(false)
      }else{
        setMatchPassward(true)
      }

    };
    
   const  confirmHandleClickShowPassword = () => {
       setShowconfirmPassword(!showPassword)
    };
    const checkboxChange=()=>{
        setCheckbox(!checkbox)
    }

    const handleMouseDownPassword=()=>{

    }

    const submitFormUser=(event)=>{
        event.preventDefault();
          createUser(
            { 
              variables:{
                    userData:{
                        username: "RajdeepSingh420",
                        email: "RajdeepSingh420@GMAIL.COM",
                        password: "RajdeepSingh420",
                        revokeJwtUserSecret: true,
                        displayName: "Rajdeep Singh 420",
                        clientMutationId: "registerUser",
                        nicename: "RajdeepSingh420",
                        registered: "true", 
                    }
                }
            }
        );
        // for debugging
        console.log(createUser , ' inside singup createUser ')
    }
    // testing show error 
    
    console.log(data, ' submit Form  test maybe workING 78') // undefined 
    console.log(error, ' submit Form  test maybe error 58')  // Network error: Unexpected end of JSON input

        return (
                <Container className={style.containerBox}>
                    <Card className={style.root} >
                        <div className={style.innerCard}>
                            <div className={style.details}>
                                <CardContent className={style.cardContentInner}>
                                    <Typography className={style.typeH5} component="h6" variant="h6">
                                        Welcome Back!
                                    </Typography>
                                    <Typography className={style.typeH3} component="h3" variant="h2">
                                        Learn With Me
                                    </Typography>
                                    <form 
                                           //  on Submit handler  
                                        onSubmit={submitFormUser}
                                        className={style.form}
                                        noValidate autoComplete="off"
                                      >
                                        <TextField onChange={(e)=>setDisplayName(e.target.value)} id="fullName" className={style.textControl} placeholder=' Exmple:Rajdeep Singh  ' label="Full Name" />
                                        <TextField onChange={(e)=>setuserName(e.target.value)}  id="userName" className={style.textControl} placeholder=' Exmple:Officialrajdeepsingh  ' label="User Name" />
                                        <TextField onChange={(e)=>setgmail(e.target.value)}  id="userGmail" className={style.textControl} placeholder=' 123@gmail.com  ' label="Gmail" />

                                        <FormControl className={style.textControl} >
                                            <InputLabel htmlFor="password">Password</InputLabel>
                                            <Input
                                                id="password"
                                                type= {showPassword ? 'text' : 'password'}
                                                value={passward}
                                                onChange={handleChange}
                                                placeholder='Exmple: Rb@1%2^3*56'
                                                endAdornment={
                                                    <InputAdornment position="end">
                                                        <IconButton
                                                            aria-label="toggle password visibility"
                                                            onClick={handleClickShowPassword}
                                                            onMouseDown={handleMouseDownPassword}
                                                        >
                                                            {showPassword ? <Visibility /> : <VisibilityOff />}
                                                        </IconButton>
                                                    </InputAdornment>
                                                }
                                            />
                                        </FormControl>

                                        <FormControl className={style.textControl} >
                                            <InputLabel htmlFor="confirmPassword">Confirm Password</InputLabel>
                                            <Input
                                                id="confirmPassword"
                                                type= {showconfirmPassword ? 'text' : 'password'}
                                                value={confirmPassword}
                                                onChange={confirmHandleChange}
                                                error={matchPassward}
                                                paceholder='Exmple Confirm Passward :  Rb@1%2^3*56'
                                                endAdornment={
                                                    <InputAdornment position="end">
                                                        <IconButton
                                                            aria-label="toggle password visibility"
                                                            onClick={confirmHandleClickShowPassword}
                                                            onMouseDown={handleMouseDownPassword}
                                                        >
                                                            {showPassword ? <Visibility /> : <VisibilityOff />}
                                                        </IconButton>
                                                    </InputAdornment>
                                                }
                                            />
                                        </FormControl>

                                        <FormControlLabel
                                            control={
                                                
                                                <Checkbox
                                                    checked={checkbox}
                                                    onChange={checkboxChange}
                                                    name="checkBox"
                                                    color="primary"
                                                    className={ style.checkBox }
                                                />

                                            }
                                            
                                            label="I Agree to Terms & Conditions "
                                            
                                        />
                                        
                                        <Button type="submit"
                                            //  send data on this button 
                                           className={style.productButton} size="small">
                                               Submit
                                    </Button>
                                    </form>


                                </CardContent>
                                

                                <div className={style.typeLogin}> 
                                    <>
                                        <Typography className={style.anchorLink}  component="h6" variant="h6">
                                                Login With Me 
                                        </Typography>
                                        <Link  href="/login">
                                             <a> Click Here  </a> 
                                        </Link>
                                    </>

                                </div>    

                            </div>

                            <CardMedia
                                component="img"
                                alt="Contemplative Reptile"
                                image='https://source.unsplash.com/random'
                                title="Live from space album cover"
                                className={style.cardImage}
                            />

                        </div>
                    </Card>
                </Container>
        )
    
}
4

0 回答 0