LoginSignup
7
4

More than 5 years have passed since last update.

Vue.jsでSequelizeから取得したデータをv-forしようとしてはまった話

Posted at

前提

  • Vue.js 2.5.8
  • Sequelize 4.22.13
  • express-vueによりサーバーサイドからVue.jsへデータを渡す形

やりたかったこと

Vue.jsの特徴といえば単一ファイルコンポーネントです。
コンポーネントを細かく分けることでソースコードの見通しがよくなり、整備性もよくなります。
そこで、データベースから取得したデータをカラム数などに関係なく共通のコンポーネントで表示できないか?となりました。

普通に考えれば…

データが格納されているオブジェクトを"datas"とします。

sample.vue
<template>
    <table>
        <tr>
            <td v-for="value in columns">
                {{value}}
            </td>
        </tr>
        <tr v-for="(row, index) in datas">
            <td v-for="col in columns">
                {{ row[col] }}
            </td>
        </tr>
    </table>
</template>

<script>
export default {
    data: function () {
        return {
            title: 'Sample',
        }
    },
    props: ['datas'],
    computed: {
        columns: function() {
            return Object.keys(this.datas[0]);
        },
    }
}
</script>

<style lang="css">

</style>

このように、v-forを入れ子にすれば表示されるはずです。
実際、[{id: 1, name: 'test'}, {id: 2, name: 'test2'}]のような簡単な構造のオブジェクトではこれで正常に表示されました。

しかし…

sequelizeで取得したテーブルデータを流し込むと、
TypeError: Converting circular structure to JSON
と例外が飛ばされてしまいます。
JSON.stringifyを行う際、オブジェクトに循環参照が含まれていると表示される例外のようです。

解決策

Vue.jsに渡すオブジェクトを一度JSON.stringifyしてから再度JSON.parseします。

sample.js
db.Sample.findAll().then(samples => {
    const data = {
        response: JSON.parse(JSON.stringify(samples))            
    };
    const vueOptions = {
        head: {
            title: 'Sample'
        }
    };
    res.renderVue('database/samples', data, vueOptions);
});

あまりきれいな解決法ではないかもしれませんが、とりあえずということで。

おわりに

原因を探るためにいろいろ調べていた時、「Vue.jsって単にconsole.log()しただけじゃreactivegetter()とかreactivesetter()になって中の値表示してくれないの何とかならないのかなぁ」と思って気分転換に調べてみたら、ネットの海に「一度JSON文字列に直す」という解決法が示されていて、「もしかしていけるのでは?」と今回の件に使ってみた結果がこれです。
数時間をドブに捨てました。

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4