简体   繁体   中英

Returns object / JSON value instead of full value, React, Graphql, Nextjs

Currently seeing an object output of {value=1, label=USA}JSON 输出 1

Instead, I want to access just the label output USA on my-post page

I am able to access post.countries ? countries.label : "" post.countries ? countries.label : "" on create-post, once I submit I see Full JSON in console view screenshot

标签访问 JSON 输出 2

Any help around this is greatly apprecited

Apologise if this is a duplicate

// pages/my-posts.js
import { useState, useEffect } from 'react'
import Link from 'next/link'
import { API, Auth } from 'aws-amplify'
import { postsByUsername } from '../graphql/queries'
import { deletePost as deletePostMutation } from '../graphql/mutations'
import MySelect from '../components/Autocomplete'
const initialState = { title: '', content: '', category: '', countries: '', createdAt: new Date().toISOString() }


export default function MyPosts() {
    const [posts, setPosts] = useState([])
    const [post, setPost, state] = useState(initialState)
    const { title, content, category, countries, createdAt } = post
    const [noOfElement, setnoOfElement] = useState(4)

    const slice = posts.slice(0, noOfElement)
    const loadMore = () => {
        setnoOfElement(noOfElement + noOfElement)
    }
    useEffect(() => {
    fetchPosts()
    }, [])
    async function fetchPosts() {
    const { username } = await Auth.currentAuthenticatedUser()
    const postData = await API.graphql({
        query: postsByUsername,
        variables: { username }
    })
    setPosts(postData.data.postsByUsername.items);
    console.log('console', postData.data.postsByUsername.items);
    
    }
    async function deletePost(id) {
    await API.graphql({
        query: deletePostMutation,
        variables: { input: { id } },
        authMode: "AMAZON_COGNITO_USER_POOLS"
    })
    fetchPosts()
    }
    

    return (
    <div>
        <h1 className="text-3xl font-semibold tracking-wide mt-6 mb-2">My Posts</h1>
        {
        slice.map((post, index) => (
            <div key={index} className="border-b border-gray-300    mt-8 pb-4">
            <h2 className="text-xl font-semibold">Title: {post.title}</h2>
            <p className="text-gray-500 mt-2 mb-2">Author: {post.username}</p>
            <h2 className="text-xl font-semibold">Author's  Category: {post.category}</h2>
            <h2 className="text-xl font-semibold">Author's  Country:  {post.countries}</h2>
            
            <time dateTime={post.createdAt}>
                    {new Date(post.createdAt).toDateString()}</time>
            <Link href={`/edit-post/${post.id}`}><a className="text-sm mr-4 text-blue-500">Edit Post</a></Link>
            <Link href={`/posts/${post.id}`}><a className="text-sm mr-4 text-blue-500">View Post</a></Link>
            <button
                className="text-sm mr-4 text-red-500"
                onClick={() => deletePost(post.id)}
            >Delete Post</button>
            </div>
        ))
        }
        <button type="button" 
        onClick={() => loadMore()}
        >
        Load more posts
        </button>
    </div>
    )
}

Create-post.js

import { withAuthenticator } from '@aws-amplify/ui-react'
import { useState, useRef } from 'react' // new
import { API, Storage } from 'aws-amplify'
import { v4 as uuid } from 'uuid'
import { useRouter } from 'next/router'
import SimpleMDE from "react-simplemde-editor"
import "easymde/dist/easymde.min.css"
import { createPost } from '../graphql/mutations'
import MySelect from '../components/Autocomplete'

const initialState = { title: '', content: '', category: '', countries: '', createdAt: new Date().toISOString() }

function CreatePost() {
  const [post, setPost, state] = useState(initialState)
  const hiddenFileInput = useRef(null);
  const { title, content, category, countries, createdAt } = post
  const router = useRouter()
  function onChange(e) {
    setPost(() => ({ ...post, [e.target.name]: e.target.value }))
  }
  
  async function createNewPost() {
    if (!title || !content || !category || !countries || !createdAt) return
    const id = uuid() 
    post.id = id
    await API.graphql({
      query: createPost,
      variables: { input: post },
      authMode: "AMAZON_COGNITO_USER_POOLS"
    })
    router.push(`/posts/${id}`)
  }
  state = {
    selected: null
  };
     console.log('countries', post.countries ? countries.label : "")
 
  return (
    <div>
      <h1 className="text-3xl font-semibold tracking-wide mt-6">Create new post</h1>
      <input
        onChange={onChange}
        name="title"
        placeholder="Title"
        value={post.title}
        className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
      /> 
      <input
        onChange={onChange}
        name="category"
        placeholder="Author Category"
        value={post.category}
        className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
      />
      <input
        onChange={onChange}
        name="createdAt"
        placeholder="Time created"
        value={post.createdAt}
        className="invisible"
      />
      <MySelect
          options={options}
          name="countries"
          onChange={onChange => setPost({ ...post, countries: onChange })}
          value={post.countries}
        />
         <div>label: {post.countries ? countries.label : ""}</div>
      <SimpleMDE value={post.content} onChange={value => setPost({ ...post, content: value })} />
      <button
        type="button"
        className="mb-4 bg-blue-600 text-white font-semibold px-8 py-2 rounded-lg"
        onClick={createNewPost}
      >Save Article</button>
    </div>
  )
}
const options  = [
  {
    value: "1",
    label: "Australia"
  },
  {
    value: "2",
    label: "New Zealand"
  },
  {
    value: "3",
    label: "USA"
  },
  {
    value: "4",
    label: "Italy"
  }
];

export default withAuthenticator(CreatePost)
type Post @model
  @key(name: "postsByUsername", fields: ["username"], queryField: "postsByUsername")
  @auth(rules: [
    { allow: owner, ownerField: "username" },
    { allow: public, operations: [read] }
  ])  {
  id: ID!
  title: String!
  category: String!
  countries: String!
  createdAt: String!
  content: String!
  username: String
}

onChange={onChange => setPost({ ...post, countries: onChange.value })} .value reutrns the value not object

import { withAuthenticator } from '@aws-amplify/ui-react'
import { useState, useRef } from 'react'
import { API, Storage } from 'aws-amplify'
import { v4 as uuid } from 'uuid'
import { useRouter } from 'next/router'
import SimpleMDE from "react-simplemde-editor"
import "easymde/dist/easymde.min.css"
import { createPost } from '../graphql/mutations'
import MySelect from '../components/Autocomplete'
// import MyCategorySelect from '../components/Category'
import { useForm } from "react-hook-form";
import { ErrorMessage } from '@hookform/error-message';
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";


const initialState = { title: '', content: '', category: '', countries: '', select: '', date: '', createdAt: new Date().toISOString()}

function CreatePost() {
  const [startDate, setStartDate] = useState(new Date());

  const { register, handleSubmit, formState: { errors } } = useForm();
  const onSubmit = data => console.log(data);

  const [post, setPost, state] = useState(initialState)
  const hiddenFileInput = useRef(null);
  const { title, content, category, countries, select, date,  createdAt } = post

  const router = useRouter()
  function onChange(e) {
    setPost(() => ({ ...post, [e.target.name]: e.target.value }))
  }
  
  console.log('setPost', post.countries ? countries.label : "")
  async function createNewPost() {
    //if ( !title || !content || !category || !countries || !select || !date ||  !createdAt ) return
    const id = uuid() 
    post.id = id
    await API.graphql({
      query: createPost,
      variables: { input: post },
      authMode: "AMAZON_COGNITO_USER_POOLS"
    })
    router.push(`/posts/${id}`)
  }
  return (
    <form onSubmit={handleSubmit(onSubmit)} autoComplete="off"
      noValidate>
    <div>
      <h1 className="text-3xl font-semibold tracking-wide mt-6">Create New Article</h1>
      <p className="mt-6">Enter Title: </p>
      <input
        aria-invalid={errors.title ? "true" : "false"}
        {...register('title', { required: true })}
        onChange={onChange}
        name="title"
        placeholder="Title"
        value={post.title}
        className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
        
      />
      {errors.title && (
        <span role="alert" className="mb-4 mt-4 alert">
          This field is required
        </span>
      )}
      <p>Enter Author's Category: </p>
      <input
        aria-invalid={errors.category ? "true" : "false"}
        {...register('category', { required: true })}
        onChange={onChange}
        name="category"
        placeholder="Author Category"
        value={post.category}
        className="mb-4 mt-4 border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
      />
      {errors.category && (
        <span role="alert" className=" alert">
          This field is required
        </span>
      )}
      <p  className="mb-2 mt-2" >Select Created Date: </p>
      <DatePicker
        // onChange={(date) => setStartDate(date)} 
        aria-invalid={errors.date ? "true" : "false"}
         {...register('date', { required: true })}
         selected={post.date}
        onChange={(date) => setPost({...post, date})}
        name="date"
        placeholder="Created date"autoComplete
        //value={post.date}
        className="visible focus:outline-black outline-black"
        
      />
      {errors.date && (
        <span role="alert" className="mb-12 mt-12 alert">
          This field is required
        </span>
      )}
      <div className="mb-2 mt-2">
      <p>Select Author's Country: </p>
      <MySelect
        aria-invalid={errors.countries ? "true" : "false"}
          {...register('countries', { required: true })}
          options={options}
          name="countries"
          onChange={onChange => setPost({ ...post, countries: onChange.value })}
          value= {post.countries}
          className="m-6"
          placeholder="Countries Select..."
        />
        </div>
        <div className="ml-6 alert">
      {errors.countries && (
        <span role="alert" className="mb-12 mt-12 alert">
          This field is required
        </span>
      )}
      </div>
       <div className="mb-2 mt-2">
      <p>Select Blog's Category: </p>
      <MySelect
        aria-invalid={errors.select ? "true" : "false"}
          {...register('select', { required: true })}
          options={selectCategoryOptions}
          name="select"
          onChange={onChange => setPost({ ...post, select: onChange.label})}
          value= {post.select}
          className="m-6"
          placeholder="select Select..."
        />
        </div>
        <div className="ml-6 alert">
      {errors.select && (
        <span role="alert" className="mb-12 mt-12 alert">
          This field is required
        </span>
      )}
      </div>
      <div className="mb-2 mt-2">
      </div>
         <p className="mt-8" >Enter Blog Content: </p>
      <SimpleMDE 
          aria-invalid={errors.content ? "true" : "false"}
            {...register('content', { required: true })}
          value={post.content} 
          onChange={value => setPost({ ...post, content: value })} 
          />
      {errors.content && (
        <span role="alert"  className="mb-4 mt-4 alert">
          This field is required
            <br/>
            <p className="alert font-semibold"> 
          Please check all fields are filled in  & wait 3 seconds before refreshing the page
          </p> 
          </span>
      )}
       <input
        onChange={onChange}
        name="createdAt"
        placeholder="Time created"
        value={post.createdAt}
        className="invisible"
        
      />
      <br/>
      
      <button
        type="submit"
        className="mb-4 mt-4 bg-blue-600 text-white font-semibold px-8 py-2 rounded-lg"
        onClick={createNewPost}
      >Save Article</button>
    </div>
    </form>
  )
}
const selectCategoryOptions  = [
  {
    label: "Sport"
  },
  {
    label: "News"
  },
  {
    label: "Weather"
  },
  {
    label: "Other"
  }
];
const options = [
  { label: 'Africa', value: 'Africa' },
  { label: 'USA', value: 'USA' },
  { label: 'Asia', value: 'Asia' },
  { label: 'Europe', value: 'Europe' },
  { label: 'Oceania', value: 'Oceania' },
]

export default withAuthenticator(CreatePost)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM