sei-ec-remote / project-4-issues

Open an issue to receive help on project 4
0 stars 0 forks source link

POST 404 #264

Closed noahD0zer closed 9 months ago

noahD0zer commented 9 months ago

What stack are you using?

(ex: MERN(mongoose + react), DR(django + react), PEN, etc.)

mern

What's the problem you're trying to solve?

404 when trying to POST to database

Post any code you think might be relevant (one fenced block per file)

//arc/api/characters.js
// CREATE -> Add Character
export const CreateCharacter = (user, newCharacter) => {
    return axios({
        url: `${apiUrl}/characters`,
        method: 'POST',
        headers: {
            Authorization: `Token token=${user.token}`
        },
        data: { character: newCharacter }
    })
    .catch((error) => {
        console.error('Error creating character:', error);
        throw error;
    });
}
//models/character.js
const mongoose = require('mongoose')

const charSchema = new mongoose.Schema(
    {
        name: {
            type: String,
            required: true,
        },
        background: {
            type: String,

        },
        race: {
            type: String,

        },
        characterClass: {
            type: String,

        },
        weaponProficiencies: [String],
        armorProficiencies: [String],
        skillProficiencies: [String],
        owner: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        },
    },
    {
        timestamps: true,
        toObject: { virtuals: true },
        toJSON: { virtuals: true }
    }
)

module.exports = mongoose.model('Character', charSchema);
//routes/charactercreate_routes.js

const express = require('express');
const router = express.Router();
const Background = require('../models/background');
const Class = require('../models/class');
const Race = require('../models/race');
const Proficiency = require('../models/proficiency');
const Character = require('../models/character');

router.get('/backgrounds', async (req, res) => {
  try {
    const backgrounds = await Background.find({}); // Fetch background names
    res.status(200).json(backgrounds);
  } catch (err) {
    console.error('Error fetching backgrounds:', err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

router.get('/races', async (req, res) => {
    try {
      const races = await Race.find({}); // Fetch race names
      res.status(200).json(races);
    } catch (err) {
      console.error('Error fetching races:', err);
      res.status(500).json({ error: 'Internal server error' });
    }
});

router.get('/classes', async (req, res) => {
    try {
      const classes = await Class.find({});
      const classData = classes.map((classObj) => ({ class: classObj.class }));
      res.status(200).json(classData);
    } catch (err) {
      console.error('Error fetching classes:', err);
      res.status(500).json({ error: 'Internal server error' });
    }
});

router.get('/proficiencies', async (req, res) => {
    try {
      const proficiencies = await Proficiency.find({});
      res.status(200).json(proficiencies);
    } catch (err) {
      console.error('Error fetching proficiencies:', err);
      res.status(500).json({ error: 'Internal server error' });
    }
});

router.post('/characters', async (req, res) => {
    try {
      const newCharacter = new Character({
        name: req.body.name,
        background: req.body.background,
        race: req.body.race,
        characterClass: req.body.characterClass,
        weaponProficiencies: req.body.weaponProficiencies,
        armorProficiencies: req.body.armorProficiencies,
        skillProficiencies: req.body.skillProficiencies,
        owner: req.user._id,
      });

      // Save the character to the database
      const savedCharacter = await newCharacter.save();

      res.status(201).json(savedCharacter);
    } catch (error) {
      res.status(500).json({ message: 'Error creating character', error: error.message });
    }
});

module.exports = router;
//src/CreateCharacter.jsx

  const handleSubmit = async (e) => {
    e.preventDefault();

    // Validate the form data here if needed

    try {
      // Send a POST request to your server to create the character
      const response = await fetch('/characters', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(characterData),
      });

      if (response.ok) {
        const newCharacter = await response.json();
        // add sucess message
        console.log('Character created:', newCharacter);
        // add redirect to home
      } else {

        console.error('Failed to create character:', response.statusText);
      }
    } catch (error) {
      console.error('Error creating character:', error);
      // Handle unexpected errors
    }
  };
      <div>
      <h1>Create Character</h1>
      <form onSubmit={handleSubmit}>
      {/* jsx */}
              <button type="submit">Create Character</button>
      </form>
    </div>

If you see an error message, post it here. If you don't, what unexpected behavior are you seeing?

CreateCharacter.jsx:72 POST http://localhost:3000/characters 404 (Not Found) handleSubmit @ CreateCharacter.jsx:72 callCallback @ react-dom.development.js:4164 invokeGuardedCallbackDev @ react-dom.development.js:4213 invokeGuardedCallback @ react-dom.development.js:4277 invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291 executeDispatch @ react-dom.development.js:9041 processDispatchQueueItemsInOrder @ react-dom.development.js:9073 processDispatchQueue @ react-dom.development.js:9086 dispatchEventsForPlugins @ react-dom.development.js:9097 (anonymous) @ react-dom.development.js:9288 batchedUpdates$1 @ react-dom.development.js:26140 batchedUpdates @ react-dom.development.js:3991 dispatchEventForPluginEventSystem @ react-dom.development.js:9287 dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465 dispatchEvent @ react-dom.development.js:6457 dispatchDiscreteEvent @ react-dom.development.js:6430 CreateCharacter.jsx:87 Failed to create character: Not Found

What is your best guess as to the source of the problem?

Im probably not calling my api function correctly, but i can't figure out what im doing wrong.

What things have you already tried to solve the problem?

Paste a link to your repository here

asands94 commented 9 months ago

You have localhost:3000/characters in your error message but you should be posting to localhost:8000/characters. So check your apiurl file in the front end and make sure your apiUrl is correct

noahD0zer commented 9 months ago

this is my apiUrl according to my apiConfig.js

let apiUrl
const apiUrls = {
    // YOU MUST CHANGE PRODUCTION URL WHEN DEPLOYING
    production: '<replace_with_deployed_api_url>',
    development: 'http://localhost:8000',
}

if (window.location.hostname === 'localhost') {
    apiUrl = apiUrls.development
} else {
    apiUrl = apiUrls.production
}

export default apiUrl

unless im looking in the wrong place?

noahD0zer commented 9 months ago

I have not imported it in my file, will respond after i do.

asands94 commented 9 months ago

I just realized you're not doing the axios call correctly, you have await fetch('/characters') instead of referencing a GET request created in your api folder in the front end. Here's Timms pet code as an example.

First all his API calls to the backend: pet api calls Then an example of him using it to get pets: PetsIndex

noahD0zer commented 9 months ago

just saw this, will also try that thank you! sorry its taking so long for me to respond. I have to refresh my page to show new responses for some reason.

noahD0zer commented 9 months ago
  const onSubmit = (e) => {
    e.preventDefault()

    createCharacter(characterData)
        .then(() => {
          console.log('Character created:');
            // msgAlert({
            //     heading: 'Character Create',
            //     message: createCharacterSuccess,
            //     variant: 'success'
            // })
        })
        .catch((error) => {
          console.error('Error creating character:', error);
            // msgAlert({
            //     heading: 'Character Creation Failed',
            //     message: createCharacterFailure,
            //     variant: 'fail'
            // })
        })
}

made a new submit function thats closer to timms API calls, now i get a 500 error.

Screenshot 2023-10-12 at 3 15 20 PM (2)

asands94 commented 9 months ago

You may want to check your backend terminal to see more error messages. Have you tested this route in postman?

noahD0zer commented 9 months ago

yes, returning this message...

{
    "message": "Error creating character",
    "error": "Cannot read properties of undefined (reading '_id')"
}
asands94 commented 9 months ago

Perfect, so there's an issue with whatever variable _id is attached to. It seems like that variable has no value. So double check that variable (do a console log) and see what you get. If it's working in postman then the issue is likely with the data your passing in on the frontend.

noahD0zer commented 9 months ago

ok, ill update you when i get it figured out!

timmshinbone commented 9 months ago

Add requireToken to the route and that will give you access to req.user, I think that's the problem here

noahD0zer commented 9 months ago

trying that now

noahD0zer commented 9 months ago

looks like it worked, now im just getting unauthorized which is probably just an authentication issue? I feel confident continuing from here though thank you for the help!

asands94 commented 9 months ago

Yeah thats just an auth issue. Make sure you're logged in next time you make a request!

timmshinbone commented 9 months ago

You have to send the user so you can get the token, make sure you're doing that

timmshinbone commented 9 months ago

Resolved in a 1:1 with too many steps to list here.