The way i am getting data is little bit complicated. I have "tweets" array where data is stored and each tweet is a card where i successfully change style when card is clicked(markTweet function), but there are also replies for each tweet which are shown same as tweets(each reply has its own card). The way i am getting data from server:
let replies = []
for(const tweet of tweets) {
let reply = await SQL('SELECT * FROM tweet_replies WHERE tweet_replies.conversation_id = ?', tweet.tweet_id)
replies.push(reply)
}
const data = {
tweets: tweets,
page: parseInt(currentPage),
numberOfPages: arr,
replies
}
Then i have component in vue. You can see replies are stored in tweets array in each tweet as tweetReplies.
In markReply func, am succesfully adding id to array.
<template>
<div class="container-full">
<div class="tweets-container">
<div
v-for="(tweet, i) in tweets"
:key="tweet.id"
>
<div
class="tweet-card"
:class="{ selected: tweet.isSelected }"
@click="markTweet(tweet.tweet_id, i)"
>
<div class="text">
<p
v-html="tweet.tweet_text"
>
{{ tweet.tweet_text }}
</p>
</div>
</div>
<div class="replies">
<div
v-for="(reply, index) in tweet.tweetReplies"
:key="reply.tweet_id"
@click="markReply(reply.tweet_id, index)"
>
<div class="tweet-card tweet-reply">
<div class="text">
<p>
{{ reply.tweet_text }}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import { getUserToken } from '@/auth/auth'
import moment from 'moment'
import { BFormTextarea, BButton, BFormSelect } from 'bootstrap-vue'
export default {
components: { BFormTextarea, BButton, BFormSelect },
data() {
return {
tweets: [],
tweetActionIds: [],
categories: [],
}
},
beforeMount() {
this.getTweets()
},
methods: {
getTweets() {
this.tweets = []
const API_URL = `${this.$server}/api/twitter/tweets`
const params = {
token: getUserToken(),
page: this.$route.query.page,
newCurrentPage: newCurrent,
}
axios.post(API_URL, null, { params }).then(res => {
this.currentPage = res.data.page
this.numberOfPages = res.data.numberOfPages
if (res.data) {
res.data.tweets.forEach(tweet => {
const tweetData = {
id: tweet.id,
tweet_id: tweet.tweet_id,
tweet_text: htmlText,
tweet_text_en: htmlTextEn,
twitter_name: tweet.twitter_name,
twitter_username: tweet.twitter_username,
added_at: moment(String(tweet.added_at)).format(
'MM/DD/YYYY hh:mm',
),
URL: tweet.URL,
isSelected: false,
tweetReplies: [],
}
this.tweets.push(tweetData)
})
res.data.replies.forEach(reply => {
reply.forEach(r => {
this.tweets.forEach(tweet => {
if (tweet.tweet_id === r.conversation_id) {
tweet.tweetReplies.push(r)
}
})
})
})
}
})
},
markTweet(tweetId, i) {
const idIndex = this.tweetActionIds.indexOf(tweetId)
this.tweets[i].isSelected = !this.tweets[i].isSelected
if (this.tweetActionIds.includes(tweetId)) {
this.tweetActionIds.splice(idIndex, 1)
} else {
this.tweetActionIds.push(tweetId)
}
},
markReply(replyId) {
const idIndex = this.tweetActionIds.indexOf(replyId)
if (this.tweetActionIds.includes(replyId)) {
this.tweetActionIds.splice(idIndex, 1)
} else {
this.tweetActionIds.push(replyId)
}
},
},
}
</script>
I have tried to add replySelected
in data and then when click is triggered in markReply i changed replySelected
to true, but every reply of a tweet was then selected, which is not what i want.
2
Answers
If I understood you correctly try like following snippet:
You can build on Nikola’s answer by bypassing the extra step of adding
isSelected
to each individual Tweet by just checking if it’s in thetweetActionIds
array, and then do the same with the replies to keep it clean