Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Vue.js Basics Building a Flashcard App Deleting a Card

Jonathan Grieve
MOD
Jonathan Grieve
Treehouse Moderator 91,253 Points

Problems with delete functionality when adding in own method.

So, what I wanted to do with this video is add a deleteCard method as the alternative suggested in the video and reference that as the attribute for the v-on directive. Like so.

<ul class="flashcard-list"> 
      <li v-on:click="toggleCard(card)" v-for="(card, index) in cards">
        <p v-show="card.flipped" class="card">{{card.front}}
            <span v-on:click="deleteCard" class="delete-card">X</span>
        </p>
        <p v-show="!card.flipped" class="card">{{card.back}}
            <span v-on:click="deleteCard" class="delete-card">X</span>
        </p>
      </li>
    </ul>

This seems to have the side effect that it will only delete the visible side of the card. It will add the new card with the "back" side facing up and if I then try to delete that card, it will delete the first card completely but not the intended card.

app.js
const cards = [
    {
      front: 'The "First Computer Programmer"',
      back: 'Ada Lovelace',
      flipped: false,
    },
    {
      front: 'Invented the "Clarke Calculator"',
      back: 'Edith Clarke',
      flipped: false,

    },
    {
      front: 'Famous World War II Enigma code breaker',
      back: 'Alan Turing',
      flipped: false,
    },
    {
      front: 'Created satellite orbit analyzation software for NASA',
      back: 'Dr. Evelyn Boyd Granville',
      flipped: false,
    },
  ]; 

  //Display our data
//On click, flip cards back and forth
//Get info for new cards from the user
//Add new card when user hits enter or clicks button
//Delete cards
//Animate card flip
//Display an error message if form fields are blank.


  new Vue({
    el: '#flashcard-app',
    data: {
      cards: cards,
      cardFront: '',
      cardBack: '',
    },
    methods: {
      toggleCard: function(card){
        card.flipped = !card.flipped
      },
      addNew: function() {
        this.cards.push({
            front: this.cardFront,
            back: this.cardBack,
            flipped: false
        })
      },
      deleteCard: function(index) {
        cards.splice(index, 1);
      }
    }

  });

Doing it the videos' way seems to fix the issues but I thought it would be better to add the functionality in its own method. Any suggestions?

3 Answers

Seth Kroger
Seth Kroger
56,414 Points

I think the main issue is you aren't passing the index of the card to the function. Try:

<span v-on:click="deleteCard(index)" class="delete-card">X</span>

The back displaying is most likely from the click event bubbling upward to the card's <p> and triggering the toggle function.

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 91,253 Points

That sounds like a very good place to start :)

I had a good time trying to do things on my own... that’s probably the only thing I didn’t think of.

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 91,253 Points

Thanks, have for the most part fixed it. Still need to look at why the back side is facing but have temporarily fixed it by setting "flipped" property to true.

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 91,253 Points

Annnd I've worked it out. I was using to v-show directives rather than using v-if and v-else on the front and the back of the cards.

Seth Kroger
Seth Kroger
56,414 Points

Good job! I didn't notice it before but you should probably have this.cards.splice() instead of cards.splice().

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 91,253 Points

I've made that change, just for consistency in the code but it doesn't seem to make any difference to the functionality! :-)

Alan McClenaghan
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Alan McClenaghan
Full Stack JavaScript Techdegree Graduate 56,501 Points

Thanks for that, Seth, it got me moving in the right direction.

How do you get your code example to display as if it's in a text editor. I can't see anything to do it is the Markdown Cheatsheet.

Alan McClenaghan
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Alan McClenaghan
Full Stack JavaScript Techdegree Graduate 56,501 Points

I added (index) as Seth Kroger suggested:

<span v-on:click="deleteCard(index)" class="delete-card">X</span>

But it also needed to be added to the method itself:

deleteCard: function(index) { cards.splice(index, 1) }

you can also pass the card itself like this

<ul class="flashcard-list">
      <li v-for="card in cards">
        <p v-if="!card.flipped" 
        class="card"
        v-on:click="toggleCards(card)"> {{card.front}}
            <span class="delete-card" @click="deleteCard(card)">X</span>
        </p>
        <p v-else class="card"
        v-on:click="toggleCards(card)"
        > {{card.back}}
            <span class="delete-card" @click="deleteCard(card)" >X</span>
        </p>
      </li>
    </ul>

and then pop it out of the array like this

deleteCard(card){
        this.cards.pop(card);
      }