0
votes

I had a page on which there was a header with an input that was a search engine, a list of posts, and pagination. I decided to move the header from this file to a separate component in a separate vue file. After I did this, the search for posts by title stopped working, and I can’t add a post now either. I think that I need to import my posts into a new file for my newly created component but how to do it.

My code when it worked(before my changes)

My code is not working after the changes:

The file in which my posts situated:

<template>
  <div class="app">
    <ul>
      <li v-for="(post, index) in paginatedData" class="post" :key="index">
        <router-link :to="{ name: 'detail', params: {id: post.id, title: post.title, body: post.body} }">
          <img src="src/assets/nature.jpg">
          <p class="boldText"> {{ post.title }}</p>
        </router-link>
        <p> {{ post.body }}</p>

    </li>

  </ul>
  <div class="allpagination">
    <button type="button" @click="page -=1" v-if="page > 0" class="prev"><<</button>
    <div class="pagin">
      <button class="item"
      v-for="n in evenPosts"
      :key="n.id"
      v-bind:class="{'selected': current === n.id}"
      @click="page=n-1">{{ n }} </button>
    </div>
    <button type="button" @click="page +=1" class="next" v-if="page < evenPosts-1">>></button>
  </div>

</div>
</template>

<script>
  import axios from 'axios';
  export default {
    name: 'Pagination',
    data () {
      return {
        search: '',
        current: null,
        page: 0,
        posts: [],
        createTitle: '',
        createBody: '',
        visiblePostID: '',
      }
    },
    watch: {
      counter: function(newValue, oldValue) {
        this.getData()
      }
    },
    created(){
      this.getData()
    },
    computed: {
      evenPosts: function(posts){
        return Math.ceil(this.posts.length/6);
      },

      paginatedData() {
        const start = this.page * 6;
        const end = start + 6;
        return this.posts.filter((post) => {
          return post.title.match(this.search);
        }).slice(start, end);
      },
    },
    methods: {
      getData() {
        axios.get(`https://jsonplaceholder.typicode.com/posts`).then(response => {
          this.posts = response.data
        })
      },

    }
  }
</script>

Header vue:

AddPost
<script>
  import axios from 'axios';
  export default {
    name: 'Pagination',
    data () {
      return {
        search: '',
        current: null,
        posts: [],
        createTitle: '',
        createBody: '',
      }
    },
    created(){
      this.getData()
    },
    methods: {
      getData() {
        axios.get(`https://jsonplaceholder.typicode.com/posts`).then(response => {
          this.posts = response.data
        })
      },
      addPost() {
        axios.post('http://jsonplaceholder.typicode.com/posts/', {
          title: this.createTitle,
          body: this.createBody
        }).then((response) => {
          this.posts.unshift(response.data)
        })
      },
    }
  }
</script>

App.vue:

<template>
  <div id="app">
    <header-self></header-self>
    <router-view></router-view>
  </div>
</template>

<script>

export default {
  components: {
    name: 'app',
  }
}
</script>
1

1 Answers

0
votes

You have a computed property paginatedData in your "posts" component that relies a variable this.search:

paginatedData () {
  const start = this.page * 6;
  const end = start + 6;
  return this.posts.filter((post) => {
    return post.title.match(this.search);
  }).slice(start, end);
},

but this.search value is not updated in that component because you moved the search input that populates that value into the header component.

What you need to do now is make sure that the updated search value is passed into your "posts" component so that the paginatedData computed property detects the change and computes the new paginatedData value.

You're now encountering the need to pass values between components that may not have a parent/child relationship.

In your scenario, I would look at handling this need with some Simple State Management as described in the Vue docs.

Depending on the scale of you app it may be worth implementing Vuex for state management.