WDI-SEA / project-2-issues

0 stars 0 forks source link

unable to call api inside of post route #42

Closed dinosaur96m closed 2 years ago

dinosaur96m commented 2 years ago

When first testing my cloudinary api by running it alone in a javascript file, I had no problem uploading a local photo to cloudninary and getting the url that now hosted the photo in a response. Instead of using fetch or axios, cloudinary provides an SDK that I used to upload my photos.

Now when I try to upload a photo to cloudinary inside of my post route, it appears that the cloudinary.uploader method never runs. Additionally, within in my router.post(), I am trying to save the url from cloudinary into a variable so I can pass it to a new item that i create in the database.

This is my code at the moment inside of controllers/items.js :

const express = require('express')
const isLoggedIn = require('../middleware/isLoggedIn')
//const cloudinaryUp = require('../middleware/cloudinaryUp')
const router = express.Router()
const cloudinary = require('cloudinary').v2
const db = require('../models')

//configure cloudinary
cloudinary.config({ 
    cloud_name: 'dunp6efgl', 
    api_key: process.env.API_KEY, 
    api_secret: process.env.API_SECRET,
    secure: true
});

break

router.post('/', isLoggedIn, (req, res) => {
    // Node.js SDK Uploader function returns a Promise
    cloudinary.uploader
    .upload(req.body.route, {
    //image is the default resour4ce type if you don't specify
    resource_type: 'image',
    })
    .then((result) => {
        //JSON.stringify will provide a formatted string
        //1st param is the value to be output
        //2nd param null is a function that can be applied to the output 
        //3rd param is the number of space characters to use for whitespeace in formatting the output
        console.log("success", JSON.stringify(result, null, 2))
        url = JSON.stringify.result.url
           //Create new ITEM in the DB
        db.item.create({
            size: req.body.size,
            type: req.body.type,
            brand: req.body.brand,
            price: req.body.price,
            imgUrl: 'test test, url not from cloudinary',
            //SequelizeValidationError: string violation: imgUrl cannot be an array or an object
            available: true,
            userId: 1,
            cartId: null,
        })
        .then(createdItem => {
            console.log(`new item added: ${JSON.stringify(createdItem)}`)
        })
    })
    .catch((error) => {
        console.log('error', JSON.stringify(result, null, 2))
    })
    // res.send(url)
    res.redirect('/items')
})

Here is the ejs file (views/items/new.ejs) containing the form I am referencing with req.body:

<h1>Sell</h1>

<!-- form for adding a new item to the db -->
<form action="/items" method="POST">
    <label for="itemType">Garment Type</label>
    <input type="text" id="itemType" name="type">

    <label for="itemSize">Size</label>
    <input type="text" id="itemSize" name="size">

    <label for="itemBrand">Brand</label>
    <input type="text" id="itemBrand" name="brand">

    <label for="itemPrice">Price</label>
    <input type="number" min="0" step=".10" id="itemPrice" name="price">

    <label for="imgRoute">Image Route</label>
    <input type="text" id="imgRoute" name="route">

    <input type="submit" value="add to your store">
</form>

It seems that no matter how I refactor, cloudinary.uploader doesn't run when using the post route.

What I've tried so far:

Error Message:

timmshinbone commented 2 years ago

console.log(cloudinary.uploader) at the top of the route, tell me here what it says

dinosaur96m commented 2 years ago
{
  unsigned_upload_stream: [Function (anonymous)],
  upload_stream: [Function (anonymous)],
  unsigned_upload: [Function (anonymous)],
  upload: [Function (anonymous)],
  upload_large_part: [Function (anonymous)],
  upload_large: [Function (anonymous)],
  upload_chunked: [Function (anonymous)],
  upload_chunked_stream: [Function (anonymous)],
  explicit: [Function (anonymous)],
  destroy: [Function (anonymous)],
  rename: [Function (anonymous)],
  text: [Function (anonymous)],
  generate_sprite: [Function (anonymous)],
  multi: [Function (anonymous)],
  explode: [Function (anonymous)],
  add_tag: [Function (anonymous)],
  remove_tag: [Function (anonymous)],
  remove_all_tags: [Function (anonymous)],
  add_context: [Function (anonymous)],
  remove_all_context: [Function (anonymous)],
  replace_tag: [Function (anonymous)],
  create_archive: [Function (anonymous)],
  create_zip: [Function (anonymous)],
  update_metadata: [Function (anonymous)],
  direct_upload: [Function: direct_upload],
  upload_tag_params: [Function: upload_tag_params],
  upload_url: [Function: upload_url],
  image_upload_tag: [Function: image_upload_tag],
  unsigned_image_upload_tag: [Function: unsigned_image_upload_tag],
  create_slideshow: [Function: create_slideshow],
  download_generated_sprite: [Function: download_generated_sprite],
  download_multi: [Function: download_multi]
}
tkolsrud commented 2 years ago

the cloudinary docs show the syntax for the uploader as: cloudinary.v2.uploader.upload(file, options, callback);

Does your endpoint include a version number?

dinosaur96m commented 2 years ago

i think I savedthe version number to a variable when I required cloudinary at the top of the file const cloudinary = require('cloudinary').v2 , so it should be there every time cloudinary is called

dinosaur96m commented 2 years ago

30C4F43E-B0A2-4B50-A3BF-14730B47255C

Oh yes, here’s the screenshot from the video in their docs where I saw them do this (full video can be found at the link at the top of this issue)

tkolsrud commented 2 years ago

Well that's a clever thing to do

dinosaur96m commented 2 years ago

Last night I started following along with this example on the Uploading Assets page of the cloudinary docs, found in the section titled Example 2: upload multiple files using a form (signed). I integrated most of this code with my project, and worked out most of the errors I was getting after doing so. I can see the form on my browser for uploading files to cloudinary, but have yet to succeed at uploading an asset from the post route.

tkolsrud commented 2 years ago

Got it. Well done finding an outside resource to help with your debugging. Are you getting any error on the post route, or just zero response from the db?

dinosaur96m commented 2 years ago

right now I'm not just not getting a response from the api. Right now it looks like there is a java script file from the docs that is handling the direct post to the api, and re: my console logs it doesn't seem to be running in response to the submit button (there is an event listener in the js file). I should probably also note that before I got into this mess with the api I was able to add new items to the database with this POST route, but using local routes for my photos (not uploading anything to cloudinary)

tkolsrud commented 2 years ago

Ahhhh right I forgot that the whole point of this api is that you're not storing photos directly in your db*

dinosaur96m commented 2 years ago

yeah exactly, for now I'm just messing with the relative path to said js file from the script tag in my ejs file. I might also try putting the script tag in my layout.ejs instead of new.ejs

dinosaur96m commented 2 years ago

currently trying to integrate the code from said js file into my router.post(), it uses fetch, but it doesnt seem to be letting me import node-fetch to the controller file, so i'm going to try replacing fetch with axios

TaylorDarneille commented 2 years ago

convert it to axios - slack me if you need help with that

dinosaur96m commented 2 years ago

slacked you! I am also now getting and error that 'document' is not defined from const form = document.querySelector("form") are we unable to use query selectors in post routes? It looks like this code is trying to grab the form data by selecting it on the document

  const form = document.querySelector("form");
    ///after submit event listener in uploadClientForm.js
    // e.preventDefault();
    console.log('uploadClientForm running')
    const files = document.querySelector("[type=file]").files;
    const formData = new FormData();

maybe there is another way to grab the form data, but whenever i console log JSON.stringify(req.body) it returns an empty object

TaylorDarneille commented 2 years ago

sent Dino a repo link of a bare bones implementation example (he also sent it to isaac). He'll follow up in a bit.

dinosaur96m commented 2 years ago

I added code from the second link taylor shared w isaac and myself, now the browser is telling me cannot POST /

dinosaur96m commented 2 years ago

Said link has two post routes, one for the multer npm and one for cloudinary. I tried running the routes with one and then the other commented out, to see if i could isolate which one was causing the issue. I also tried moving my get route for the upload form above these post routes, but in all these scenarios I'm still getting cannot POST / I also created a directory called 'uploads' in the same directory as my controller file, to correlate with this line of code: const upload = multer({ dest: './uploads/' });, but this did not change anything either.

dinosaur96m commented 2 years ago

Taylor got me uploading to cloudinary on zoom! Elimnating all the fancy lines of configuration re: the cloudinary SDK and only using the CLOUDINARY_URL to configure solved it. Never using an SDK again :')