0

I am creating a simple SPA using vue.js and axioz as a scripts (not cli, etc)

So far I am able to pull data from a json then render and paginate the list,and when an item is clicked I am able to console log the data for the specific entry.

HTML

<!--app-->
<div id="app">

    <!--articles-->
    <div class="row" style="background: #111; padding: 8em 0; width: 50%;">
            <div class="ctr">
                <div class="row articles page_content" style="padding: 0;">
                    <ul>
                        <li v-for="(post) in displayedPosts" @click="getSingle(post.id)">
                            <router-link :to="{ path: '/post/'+ post.id}" class="flex" >
                                <div class="row article_thumb">
                                    <img :src="post.url" :alt="post.title"/>
                                </div>
                                <div class="row article_excerpt">
                                    <h3 class="title">{{post.title }}</h3>
                                </div>
                            </router-link>
                        </li>
                    </ul>
                </div>
                <div class="row pagination">
                    <button type="button" v-if="page != 1" @click="page--"> << </button>
                    <button type="button" v-for="pageNumber in pages.slice(page-1, page+5)" @click="page = pageNumber"> {{pageNumber}} </button>
                    <button type="button" @click="page++" v-if="page < pages.length"> >> </button>
                </div>
            </div>
        </div>
        <!--articles-->

        <div class="row" style="background: #000; padding: 8em 0; width: 50%;">
            <div class="flex router">
                <router-view></router-view>
            </div>
        </div>

</div>
<!--app-->

VUE.JS

const Home = {
  template: "<div><h1>Click an article to update this view</h1></div>"
};

//post
var Post = {
  template:
    '<div class="row"><h1>Display data for Post ID  # {{$route.params.id}} here</h1><p style="color: red;">This is where I am stuck, cant display the post data, see example below.</p><p>{{title}}</p></div>',

  //post methods
  methods: {
    //get single post
    getSingle: function(id) {
      var self = this;
      this.id = this.$route.params.id;
      this.title = this.title;
      axios
        .get(this.baseUrl, {
          params: {
            id: this.id,
          }
        })
        .then(response => {
          this.post = response.data;
          this.title = response.data.title;
          console.log(this.title);
          console.log(this.post);
          console.log("You clicked post ID #" + this.id);
        })
        .catch(response => {
          console.log(error);
        });
    }
  },
  //post methods

  //post data
  data() {
    return {
      baseUrl: "https://jsonplaceholder.typicode.com/photos",
      posts: [],
      title: this.title
    };
  },

  //post created
  created() {
    this.getSingle(this.$route.params.id);
  },

  watch: {
    "$route.params": {
      handler(newValue) {
        const { id } = newValue;
        this.getSingle(id);
      },
      immediate: true
    }
  }
};
//post

//router
const router = new VueRouter({
  routes: [
    { path: "/", component: Home },
    { path: "/post/:id", component: Post }
  ]
});

//initial state
var paginationApp = new Vue({
  el: "#app",
  router: router,
  data: {
    posts: [],
    baseUrl: "https://jsonplaceholder.typicode.com/photos",
    page: 1,
    perPage: 2,
    pages: []
  },

  //initial state methods
  methods: {

    //get single
    getSingle() {},

    //get posts
    getPosts() {
      axios
        .get(this.baseUrl)
        .then(response => {
          this.posts = response.data;
        })
        .catch(response => {
          console.log(response);
        });
    },

    //set pages
    setPages() {
      let numberOfPages = Math.ceil(this.posts.length / this.perPage);
      for (let index = 1; index <= numberOfPages; index++) {
        this.pages.push(index);
      }
    },

    //paginate
    paginate(posts) {
      let page = this.page;
      let perPage = this.perPage;
      let from = page * perPage - perPage;
      let to = page * perPage;
      return posts.slice(from, to);
    }
  },

  //created
  created() {
    this.getPosts();
  },

  //watch
  watch: {
    posts() {
      this.setPages();
    }
  },

  //computed
  computed: {
    displayedPosts() {
      return this.paginate(this.posts);
    }
  }
});
//initial state

Or see this codepen for full example https://codepen.io/flashvenom/pen/YozyMx and be sure to checkout the console log.

My problem is i cannot console log the title or any internal fields of the data object, as I want to be able to add the title etc into the view area.

Any help or pointers would be much appreciated.

Dan W
  • 138
  • 3
  • 14
  • 1
    Use axios callback. Here's a link you might be interested in. (https://stackoverflow.com/questions/50591829/how-can-i-populate-an-axios-get-data-array-and-pass-it-to-a-vuejs-component-prop) – Dipesh Lohani Jun 11 '19 at 11:29

1 Answers1

2

The response is in array form and you cannot access array object element without looping array.

If you wish to get title of first post, then you can do as shown below,

this.title = response.data[0].title

To access all posts title, you can use v-for loop in you vue template. Here is little example on how you can accomplish that,

<div v-for="post in posts">
    <span>{{ post.title }}</span>    
</div>
Murtaza Bharmal
  • 472
  • 4
  • 16
  • Thanks for the quick response, yes that makes perfect sense, so i suppose if my object ids start at 0 i can just do something like, ``` this.id = this.$route.params.id; this.title = response.data[this.id].title ``` – Dan W Jun 11 '19 at 11:52
  • 1
    Your welcome. Yes you can do like that or may be this (https://stackoverflow.com/questions/53033111/v-onclick-event-vue-js-to-show-user-posts) can help you for showing single post data on click event. – Murtaza Bharmal Jun 11 '19 at 12:09
  • Ive tried ths and works a treat thanks,pen updated too if you want to check it out, i suppose the one thing i need to do now is work out how to make the id 0 dynamic to match the id of the clicked item, otherwise thanks a lot been trying to get answer to this on the vue forum for days – Dan W Jun 11 '19 at 12:14
  • What a dummy, just realised because I am already select the object the id is always 0 so works exactly as I needed it to thanks so much, highly appreciated. – Dan W Jun 11 '19 at 12:35
  • 1
    yes the id of array starts from 0 by default. You are most welcome bud. Keep coding! – Murtaza Bharmal Jun 11 '19 at 13:17