Submission of Form Data via Nextjs and Graphql Apollo - graphql

I am trying to do a POST method using ApolloGraphql Mutation into my local postgres database. I am able to query and my api works when I am adding a new item via the Apollo Graphql Client, but am trying to figure out a way to post via a form.
import type { NextPage } from 'next'
import Head from 'next/head'
import {Card} from "../components/Card"
//import {products} from "../data/products";
import {gql, useQuery, useMutation} from "#apollo/client"
import { useState } from 'react';
const AllProductQuery = gql`
query Product_Query {
products {
title
description
}
}
`;
const AddProducts = gql`
mutation Add_Product($title: String!
$description: String!
) {
product(description: $description, title: $title) {
id
description
title
}
}
`;
const Home: NextPage = () => {
const {data, error, loading} = useQuery(AllProductQuery);
const [title, setTitle] = useState("")
const [description, setDescription] = useState("")
const [createPost] = useMutation(AddProducts, {
variables: {
title,
description
}
});
if (loading) {return <p>Loading...</p>}
if(error) {return <p>{error.message}</p>}
return (
<div >
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<div className='container mx-auto my-20 px-5 '>
{data.products.map((product: any) => (
<Card key={product.id} title={product.title} description={product.description} />
))}
</div>
<form className='flex flex-col p-2' onSubmit={e => {
e.preventDefault(); createPost();
}}>
<input placeholder="Title" type='text' value={title}onChange={(e) => {setTitle(e.target.value);}} required/>
<input placeholder="Description" type='text' value={description} onChange={(e) => {setDescription(e.target.value);}} required/>
<button type="submit" className='bg-blue-500 text-white rounded-lg'>Submit</button>
</form>
</div>
)
}
export default Home
I am currently creating a [createPost] with a useMutation function and putting my variables as title and description. In the form I then apply that method. Any help would be great!

Related

React-Bootstrap dynamic Image rendering

I am trying to display profile pic by calling the path and file name from database
Profile Image is not loading is it the path?
using json server local test.
Image is saved in folder ../src/image/
json data
image: "..image/pic.jpg"
import { Card, ListGroup } from "react-bootstrap";
import { useParams, useHistory } from "react-router-dom";
import useFetch from "./useFetch";
const MemberProfile = () => {
const { id } = useParams();
const {
data: member,
error,
isLoading,
} = useFetch("http://192.168.0.23:8000/members/" + id);
const history = useHistory();
const handleClick = () => {
fetch("http://192.168.0.23:8000/members/" + member.id, {
method: "DELETE",
}).then(() => {
history.push("/");
});
};
return (
<div className="memberProfile">
{isLoading && <div>Loading...</div>}
{error && <div>{error}</div>}
{member && (
<Card style={{}}>
<Card.Img variant="top" src={member.image} />
<Card.Body>
<Card.Title>
<h2>
<strong>
Profile - {member.name} {id}
</strong>
</h2>
</Card.Title>
<Card.Text>
<pre className="acordnBody">
Gender : {member.gender} <hr />
Phone : {member.tel} <hr />
E-mail : {member.email} <hr />
Address : {member.address}
</pre>
</Card.Text>
</Card.Body>
</Card>
)}
</div>
);
};
export default MemberProfile;

I get following error: expected Name, found $ when firing a GraphQL query from React using Apollo. The query works fine in GraphiQL

Here's the GraphQL Query:
const movieByName = gql`
query SomeName($name: String!){
movieByName(name: $name){
name
genre
year
}
}`
It works fine on graphiql though and here's the Schema
type Query {
movies: [Movie],
movieByName(name: String!): Movie
}
type Movie {
name: String,
genre: String,
year: String
}
Here's the final code file:
import React, { Component } from 'react';
import {HashLink as Link} from 'react-router-hash-link'
import { graphql } from 'react-apollo';
import { gql } from "apollo-boost";
const movieByName = gql`
query SomeName($name: String!){
movieByName(name: $name){
name
genre
year
}
}`
class Header extends Component {
state = {
name: '',
genre: '',
year: ''
}
searchSubmit = (event) => {
event.preventDefault()
console.log(this.props)
}
render(){
return (
<div className="topnav">
<a className="logo" href="/">Movie Maker</a>
<div className="search-container">
<form onSubmit={this.searchSubmit}>
<Link smooth to="#form">Add Movies</Link>
<input type="text" placeholder="Search.." name="search"
onChange={(e) => this.setState({name: e.target.value})}/>
<button type="submit"><i className="fa fa-search"></i></button>
</form>
</div>
</div>
);
}}
export default graphql(movieByName)(Header)

graphql - call mutation from a form

I'm new to graphql
I have a simple react app that lists books using a graphql query that queries a mongoDB database.
The schema contains a addBook Mutation that adds books to the DB.
This works using graphiql and I can add books and display them.
My problem now is I'm trying to use this mutation to add the books from a form on the react page.
I have a addBook component and listBooks component.
I get the error TypeError: this.props.addBookMutation is not a function
addBooks.js
import React, { Component } from 'react';
import { graphql } from 'react-apollo';
import { addBookMutation } from '../queries/queries';
class AddBooks extends Component {
constructor(props) {
super(props);
this.state = {
name: "",
genre: "",
author: "",
}
}
submitForm(e) {
e.preventDefault()
this.props.addBookMutation({
variables: {
name: this.state.name,
genre: this.state.genre,
author: this.state.author,
}
})
}
render() {
return (
<div className="wrapper">
<form action="" className="o-form" onSubmit={this.submitForm.bind(this)}>
<div className="o-form__element">
<label className="o-form__label" htmlFor="">Book Name</label>
<input className="o-form__input" type="text" onChange={(e) => this.setState({ name: e.target.value })} />
</div>
<div className="o-form__element">
<label className="o-form__label" htmlFor="">Description</label>
<textarea className="o-form__input" type="text" onChange={(e) => this.setState({ genre: e.target.value })}>
</textarea>
</div>
<div className="o-form__element">
<label className="o-form__label" htmlFor="">Year</label>
<input className="o-form__input" type="text" onChange={(e) => this.setState({ author: e.target.value })} />
</div>
<button className="o-form__btn">Add Book</button>
</form>
</div>
)
}
}
export default graphql(addBookMutation)(AddBooks)
queries.js
import { gql } from 'apollo-boost';
const getBookQuery = gql`
{
fonts{
name
genre
author
}
}
`
const addBookMutation = gql`
mutation($name: String!, $genre: String!, $author: String!){
addBook(
name: $name,
genre: $genre,
author: $author
)
}
`
export { getBookQuery, addBookMutation };
you can't call this.props.addBookMutation, in your case for a class component call it by this.props.mutate({}) for more info
submitForm(e) {
e.preventDefault();
this.props.mutate({
variables: {
name: this.state.name,
genre: this.state.genre,
author: this.state.author,
}
}).catch(res => {
const errors = res.graphQLErrors.map(err => err.message);
this.setState({ errors });
});
}

How to work with axios.put and react?

I am trying create a simple crud system with react redux and form-redux.
The code below but does not work and gives error.
First I created an action for update and then created a reducer for that.
And then created component to use the action.
Let me know how to get this to work.
//-------------action--------------
export const EDIT_POST = 'EDIT_POST';
export const editPost = (id) => {
const request = axios.put(`${BOOK_URL}/books/${id}`);
return {
type: EDIT_POST,
payload: id,
}
};
//---------------- reducer-----------------
case EDIT_POST: {
return {...state, post: action.payload.data}
}
//----------------route--------------
<Route path='/posts/edit/:id' component={PostEdit}/>
//-------------------PostEdit---------------
class PostEdit extends Component {
componentDidMount = () => {
this.props.editPost(this.props.match.params.id);
console.log(this.props.editPost(this.props.match.params.id));
};
renderField = field => {
const {meta: {touched, error}} = field;
const className = `form-group ${touched && error ? 'has-danger' : ''}`;
return (
<div className='has-danger'>
<label>{field.label}</label>
<input type="text" {...field.input} className="form-control"/>
<div className="text-help">
{touched ? error : ''}
</div>
</div>
);
};
render() {
const {handleSubmit} = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmitForm)}>
<Field name="title" label="Title" component={this.renderField}/>
<Field name="author" label="Author" component={this.renderField}/>
<Field name="description" label="Description" component={this.renderField}/>
<Field name="publicationDate" label="PublicationDate" component={this.renderField}/>
<button type='submit' className="btn btn-primary">Submit</button>
<Link to='/' className='btn btn-danger'>Cancel</Link>
</form>
);
}
}
export default reduxForm({
form :'updateForm'
})(connect(null, {editPost})(PostEdit));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Could you tell what error you are getting?
You have to change your action like
export const fetchPosts = () => {
return (dispatch) => {
axios.get(`${BOOK_URL}/books`).then((response) => {
return dispatch({
type: FETCH_POSTS,
payload: // your response here
});
})
}
}

Unit test case for React Component using enzyme

I am working on reactjs 5.X version. I am writing UT with enzyme. Below is my reusable component with prop arguments. Not able to find the div tags inside of the const component.Can you help me how to get the div tags using classname or using find function to get div tags.
import React from 'react';
import styles from './democheck.css';
const democheck = ({ input, cb,
required, testCheckbox, checked, label, meta: { error } }) => (
<div id="hierrdivid" className={styles.testDivColumn}>
<div className={styles.testDiv}>
<br />
<span className={styles.testLabel}>
{label}
</span>
{required && <span className={styles.error}>
*
</span>}
<input
{...input}
name={`form-field-${input.name}`}
checked={checked}
id={input.name}
className={testCheckbox ? styles.testCheckboxError :
styles.testCheckbox}
type="checkbox"
onChange={() => {
if (cb) {
cb(document.getElementById(input.name).checked);
}
}}
/>
</div>
<div className={styles.testerrorDiv}>
{testCheckbox &&
<div className={styles.testerrorLabel}>
{label} {error}
</div>}
</div>
</div>
);
democheck.propTypes = {
input: React.PropTypes.objectOf(React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.func
])),
cb: React.PropTypes.func,
label: React.PropTypes.string,
meta: React.PropTypes.shape({}),`enter code here`
required: React.PropTypes.bool,
checked: React.PropTypes.bool,`enter code here`
testCheckbox: React.PropTypes.bool
};

Resources