reactjsgraphqlexpress-graphql

GraphQL - Query Seems Fine but Getting 400 Error


So, whenever I try to add a product to the inventory list, via a mutation, I get a POST http://localhost:3000/graphql 400 (Bad Request). I can perform the mutation in the sandbox without issue. And, the query to retrieve information works just fine. I have double-checked all the names being used and nothing seems off. Here is the code:

From App.jsx:

async createProduct(product) {
    const query = `mutation addProduct($product: ProductInputs!) {
      addProduct(product: $product) {
        id
      }
    }`;

    await fetch('/graphql', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ query, variables: { product }})
    });

    await this.loadData();
}

From schema.graphql:

enum InventoryCategory {
  Shirts
  Jeans
  Jackets
  Sweaters
  Accessories
}

type Product {
  id: Int!
  category: InventoryCategory!
  name: String!
  price: Float
  imageURL: String
}

"Toned down Product, used as inputs, without server generated values."
input ProductInputs {
  category: InventoryCategory!
  name: String
  price: Float
  imageURL: String
}

##### Top level declarations

type Query {
  productList: [Product!]!
}

type Mutation {
  addProduct(product: ProductInputs!): Product!
}

From server.js

const inventoryDB = [];

const resolvers = {
  Query: {
    productList,
  },
  Mutation: {
    addProduct,
  },
};

function productList() {
  return inventoryDB;
}

function addProduct(_, { product }) {
  product.id = inventoryDB.length + 1;
  inventoryDB.push(product);
  return product;
}

Is there anything that stands out as being obviously incorrect? I cannot seem to figure out why I keep getting the 400 error. I cannot seem to find an issue with the query (mutation) itself. Any thoughts?

Edit: The query to retrieve information works just fine. See below for the code:

async loadData() {
    const query = `query {
      productList {
        id
        category
        name
        price
        imageURL
      }
    }`;

    const response = await fetch('/graphql', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({ query })
    });

    const body = await response.text();
    const result = JSON.parse(body);
    this.setState({ products: result.data.productList });
}

Solution

  • So, I figured out the problem. The issue was with the price, which GraphQL expected to be a float, but I was sending a string. I had to convert the text input to the proper format and voila, it worked. For the conversion I used:

    parseFloat(form.price.value.substring(1))
    

    and also used:

    {new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD'}).format(product.price)}
    

    to ensure correct display formatting.