Skip to content
Advertisement

How to not insert two of the same values

I’m using an input to allow user’s to select files from their computer and add it to a list. I’m doing this by using a promise to load the files and creating an array of promises and adding that to my state

React JS

this.state = {
  files: [],
};

const readFile = (file) => {

    const fileReader = new FileReader();

    return new Promise((resolve, reject) => {

      fileReader.onerror = (error) => {
        reject({ error })
      }

       fileReader.onload = (e) => {
        resolve({
          name: file.name.replace( /_|.mp3/gi, " "),
          link: e.target.result,
          id: id++,

        })
      }

      fileReader.readAsDataURL(file);

    })
  }
  const allReaders = Array.from(event.target.files).map(readFile)

  Promise.all(allReaders)
    .then(fileList => {
      console.log(this.state.files)
      this.setState({ files: fileList });
    })
    .catch(error => {
       console.error(error)
    });


}

I’m then mapping through my files array to add those files to a list of text inputs. They’re also able to reorder the list as well as change the text for each list item.

After that they will be able to save the list information to a database using a button.

React JS

save(event) {
   event.preventDefault();
   let files = this.state.files;

let data = files.map(( { name }  , index) => ({ name, index : index }));


 let request = new Request('http://localhost:3000/songs', {
    method: 'POST',
    headers: new Headers({ 'Content-Type': 'application/json' }),
    body: JSON.stringify(data)
  });

       fetch(request)
      .then((response) =>
        response.json())
          .then((data) => {
          })
          .catch((error) => {
            console.log(error)
          })

}

Node JS

*queries.js*
const addSong = (request, response) => {
  const id = parseInt(request.params.id)
  const { name, link, index } = request.body;

for (var i = 0; i < request.body.length; i++) {
  pool.query('INSERT INTO songs (name, link, index) VALUES ($1, $2, $3) RETURNING *', [request.body[i].name, request.body[i].link, request.body[i].index], (error, results) => {
  if (error) {
    throw error
    console.log(error)
  } else {
    console.log("Rows " + JSON.stringify(results.rows));

  }
 });
}
}

*index.js*
const app = express();
const db = require('./queries');
app.post('/songs', db.addSong)

It works but if I click save twice it saves the same data to the database. I guess what I want to be able to do is not save the object if it contains the same index as another object.

Advertisement

Answer

If you want to prevent duplicates on column index (which, by the way, is not a well-chosen column name since it is a reserved workd in almost all RDBMS), you can simply add a unique constraint on that column:

ALTER TABLE songs ADD CONSTRAINT song_unique_index UNIQUE ("index");

If an attempt is made to create a duplicate, the database will raise an error. In Postgres, you can even manage that error in your query, using handy clause ON CONFLICT.

For example, you can simply ignore duplicate errors on this specific column like this:

INSERT INTO songs (name, link, index) 
VALUES ($1, $2, $3) 
ON CONFLICT (song_unique_index) DO NOTHING
RETURNING *

Duplicates will not be inserted, and no error will be raised.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement