Skip to content

Instantly share code, notes, and snippets.

@NickHatBoecker
Last active August 17, 2019 16:57
Show Gist options
  • Save NickHatBoecker/9198ffee8a2cd234ddb28f65f08115d8 to your computer and use it in GitHub Desktop.
Save NickHatBoecker/9198ffee8a2cd234ddb28f65f08115d8 to your computer and use it in GitHub Desktop.
Vuex: Add bookmark problem

I have two big arrays in the store: categories and bookmarks.

const categories = [
    {
        id: 1,
        bookmarks: [1, 2],
        title: 'Category',
    }
]

const bookmarks = [
    {
        id: 1,
        category: 1,
        title: 'Bookmark',
    }
]

I had to normalize these two, in order to work propably with vuex. Previously, I had the actual bookmarks object in category.bookmarks.

On the bookmarks page I have one active category, whose bookmarks should be displayed. So I read the active category from store and then I get its bookmarks via getCategoryBookmarks(). This method maps all store.bookmarks to the category via bookmarkId.

So far so good. When I remove a bookmark from store, the view gets updated. But when I add a bookmark the view wont get updated. I have to reload the whole page to display it.

import axios from 'axios'
import store from '@/store'
import { getCategoryBookmarks } from '@/helpers/Categories.js'
export const loadBookmarks = async () => {
const response = await axios.get(`${process.env.VUE_APP_API_BASE_URL}/get-all/`)
if (!response || !response.data) {
return []
}
return response.data
}
export const addBookmark = async (title, url, categoryId) => {
const response = await axios.post(`${process.env.VUE_APP_API_BASE_URL}/add/`, {
title: title,
url: url,
category: categoryId,
})
const bookmark = response.data
store.commit('addBookmark', bookmark)
}
export const removeBookmark = async (bookmark) => {
try {
await axios.delete(`${process.env.VUE_APP_API_BASE_URL}/delete/`, {
data: { id: bookmark.id },
})
store.commit('removeBookmark', findBookmarkIndexById(bookmark.id))
} catch (e) {
alert('ERROR: Could not delete bookmark.')
console.log(e)
}
}
export const findBookmarkIndexById = (bookmarkId) => {
return store.getters.bookmarks.findIndex(x => x.id === parseInt(bookmarkId))
}
<template>
<div class="column c-bookmarks">
<nav class="panel">
<div class="c-bookmarks__meta">
<b-button
class="c-bookmarks__add is-primary"
title="Lesezeichen hinzufügen (Ctrl+N)"
@click="test()"
icon-left="mdi mdi-bookmark-plus"
>
<small>Neu</small>
</b-button>
<b-button
class="is-default"
title="Lesezeichen aktualisieren"
@click="reload()"
icon-right="mdi mdi-reload"
></b-button>
</div>
<div class="c-bookmarks__wrapper">
<template v-if="getActiveCategory() && bookmarks.length">
<a
:href="bookmark.url"
class="panel-block"
v-for="bookmark in bookmarks"
v-bind:key="bookmark.id"
target="_blank"
:data-id="bookmark.id"
v-if="bookmark"
>
<span class="panel-icon c-bookmarks__panel-icon" @click.prevent="removeBookmark(bookmark)" title="Lesezeichen löschen">
<i class="mdi mdi-bookmark-remove" aria-hidden="true"></i>
</span>
<img class="u-mr" :src="`http://www.google.com/s2/favicons?domain=${bookmark.url}`" alt="" title="">
<span>{{ bookmark.title }}</span>
<small class="c-bookmarks__subtitle">{{ renderUrl(bookmark.url) }}</small>
</a>
</template>
<p class="panel-block" v-if="!getActiveCategory() || !bookmarks.length">
Es gibt noch keine Lesezeichen in dieser Kategorie.
<a @click="showBookmarkModal()" style="margin-left: 6px;">
<i class="mdi mdi-plus-box c-bookmarks__add-icon" aria-hidden="true"></i> Lesezeichen anlegen.
</a>
</p>
</div>
</nav>
</div>
</template>
<script>
import { getActiveCategory, getCategoryBookmarks } from '@/helpers/Categories'
import { filterBookmarks, removeBookmark } from '@/helpers/Bookmarks'
export default {
name: 'Bookmarks',
data: function () {
return {
}
},
computed: {
bookmarks: function () {
return getCategoryBookmarks(getActiveCategory())
},
},
methods: {
getActiveCategory,
removeBookmark,
getPath (category) {
return category.path.join(' > ')
},
renderUrl (url) {
if (!url) {
return ''
} else if (url.length > 100) {
return `${url.slice(0, 100)}...`
}
return url
},
test () {
addBookmark('Titel', 'https://test.de', '1')
},
reload () {
this.$store.commit('loadCategories')
this.$store.commit('loadBookmarks')
},
},
}
</script>
export default new Vuex.Store({
state: {
categories: [],
bookmarks: [],
activeMainCategory: null,
},
mutations: {
// Irrelevant
async loadCategories (state) {
state.categories = await loadCategories()
if (!state.activeMainCategory) {
this.commit('setActiveMainCategory', state.categories[0])
}
},
// Only works on init
async loadBookmarks (state) {
state.bookmarks = await loadBookmarks()
},
// Not working
addBookmark (state, bookmark) {
Vue.set(state.bookmarks, state.bookmarks.length, bookmark)
},
// Working
removeBookmark (state, index) {
Vue.delete(state.bookmarks, index)
},
// Irrelevant
setActiveMainCategory (state, category) {
Vue.set(state, 'activeMainCategory', category)
},
},
getters: {
categories: state => state.categories,
bookmarks: state => state.bookmarks,
activeMainCategory: state => state.activeMainCategory,
},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment