Search code examples
node.jsvue.jsaxioscrudv-for

Vue: v-for not rendering (using Node and Axios)


I'm trying to fetch some data from my MySql DB in the table 'clients' (to make a CRUD later on), but nothing is rendered when I try to output in a v-for. The 'ul' is rendered but its empty because the 'li's is not rendered. I don't get any error, its just not rendering?

My code is here:

Router.js (server-side):

// routes/router.js

const express = require('express');
const router = express.Router();

const bcrypt = require('bcryptjs');
const uuid = require('uuid');
const jwt = require('jsonwebtoken');

const db = require('../lib/db.js');
const userMiddleware = require('../middleware/users.js');

// (Working) code for a login - removed here to make it more simple
// (Working) code for a login - removed here to make it more simple
// (Working) code for a login - removed here to make it more simple

router.get('/clients', (req, res, next) => {
    db.query("SELECT * FROM clients", function (err, result, fields) {
        if (err) {
            res.status(400).send();
            throw err;
        }

        console.log(result);
        res.status(200).send(result);
    });
});


module.exports = router;

My Clients.vue (client-side):

<template>
  <div>

      Hi {{ username | capitalize }}

      <ul>
        <li :key="client.id" v-for="client in clients">
          <strong>{{ client.name }}</strong>
          <small>{{ client.email }}</small> | <small>{{  client.phone }}</small>
        </li>
      </ul>

      <a href="#" @click="logout">Logout</a>

  </div>
</template>

<script>
  import AuthService from '@/services/AuthService.js';
  import ClientService from '@/services/ClientService.js';

  export default {
    data() {
      return {
        secretMessage: 'Sample secret message',
        username: '',
        clients: []
      };
    },

    async created() {
      if (!this.$store.getters.isLoggedIn) {
        this.$router.push('/login');
      }
      this.username = this.$store.getters.getUser.username;
      this.secretMessage = await AuthService.getSecretContent();

      var self = this
      ClientService.getClients().then((clients) => {
        self.clients = clients;
      });

    },
    methods: {
      logout() {
        this.$store.dispatch('logout');
        this.$router.push('/login');
      }
    },
    filters: {
      capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
      }
    },
  };

</script>

And my ClientService.js looks like this:

// src/services/ClientService.js

import axios from 'axios';
const url = 'http://localhost:3000/api/';
export default {
    getClients() {
        return axios
            .get(url + 'clients/')
            .then(response => response.data);
    }
};

When I run the get request for 'http://localhost:3000/api/clients' in Postman I receive the correct data:

[
    {
        "id": 1,
        "name": "Sample Client One",
        "email": "[email protected]",
        "phone": "12345678"
    },
    {
        "id": 3,
        "name": "Sample Client two",
        "email": "[email protected]",
        "phone": "12345678"
    }
]

What am i doing wrong?

//Rue


Solution

  • Removing the async from async created() will fix the issue.

    You can read more about async functions here. The important part for your issue is that the created method, on the Vue component, is not supposed to return a Promise.