Achieve Vue to refresh the view or component

I am facing a dilemma while working on a specific component.

The component in question is called "RecentUpdates".

Within this component, I am passing props down to several other components, as indicated at the beginning of the file.

My issue arises when trying to add a new post. I am struggling to retrieve the correct update object array and also unsure about the right way to update the data prop that is passed down to the "PostList" component.

<template>
  <div>
    <PostFilter v-on:selectedCategory="getSelectedPosts" v-on:showAllPosts="showAllPosts" :user="user" :categories="categories"/>

    <PostList v-if="recent_posts[0]" :categories="categories" :posts="recent_posts[0]" :user="user"/>

    <Pagination v-on:getPreviousPage="getPreviousPage" v-on:getNextPage="getNextPage"/>
  </div>
</template>

<script>

import PostList from './PostList';
import PostFilter from './PostFilter';
import Pagination from './Pagination';
import EventBus from '../event-bus';


export default {

  name: 'RecentUpdates',

  data: () => ({
    errors: [],
    recent_posts: [],
  }),

  props: ['categories', 'user'],

  components: {
    PostList,
    PostFilter,
    Pagination
  },

  created() {

    if (this.user.meta.selected_categories[0] == 0) {
      this.showAllPosts();
    }

    // do not call here, not working as expected
    // is switching selected category to an incorrect one
    // this.updateList();

    this.getSelectedCategory();
  },

  watch: {
    recent_posts: function(newValue) {

      EventBus.$on('addPost', function(newPost) {
        console.log(newPost);

        this.$forceUpdate();


        //this.recent_posts.push(newPost);

        //this.$set(this.recent_posts, newPost, newPost);

        // this.$nextTick(function () {
        //   this.recent_posts.push(newPost);
        // });


      });

        console.log(this.recent_posts[0]);


      // this.$nextTick(function () {
      //   console.log(this.recent_posts[0]) // => 'updated'
      // });

      // if (this.user.meta.selected_categories[0] == 0) {
      //   EventBus.$on('addPost', this.showAllPosts);
      // } else {
      //   EventBus.$on('addPost', this.getSelectedCategory);
      // }
      //this.updateList();
    }
  },

  methods: {

    // updateList() {

    //   if (this.user.meta.selected_categories[0] == 0) {
    //     EventBus.$on('addPost', this.showAllPosts);
    //     //EventBus.$emit('newPost');

    //   } else {
    //     EventBus.$on('addPost', this.getSelectedCategory);
    //     //EventBus.$emit('newPost');
    //   }

    // },

    getSelectedCategory() {

      let categoryId = this.user.meta.selected_categories[0];

      this.getSelectedPosts(categoryId);
    },

    showAllPosts() {

      axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]', 
        {headers: {'X-WP-Nonce': portal.nonce}})
      .then(response => {
        this.recent_posts = [];
        //this.recent_posts = response.data;
        //console.log(response.data);
        this.recent_posts.push(response.data);
        console.log(this.recent_posts[0]);

      })
      .catch(e => {
        this.errors.push(e);
      });
    },

    getSelectedPosts(categoryId) {

      axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&categories=' + categoryId,
        {headers: {'X-WP-Nonce': portal.nonce}})
      .then(response => {
        this.recent_posts = [];
        //console.log(response.data);

        this.recent_posts.push(response.data);

        console.log(this.recent_posts[0]);


      })
      .catch(e => {
        this.errors.push(e);
      });
    },

    /**
     * Pagination methods
     *
     */
    getPreviousPage(page) {
      axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&page=' + page, 
        {headers: {'X-WP-Nonce': portal.nonce}})
      .then(response => {
        this.recent_posts = response.data;
      })
      .catch(e => {
        this.errors.push(e);
      });
    },

    getNextPage(page) {
      axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&page=' + page, 
        {headers: {'X-WP-Nonce': portal.nonce}})
      .then(response => {
        this.recent_posts = response.data;
      })
      .catch(e => {
        this.errors.push(e);
      });
    }
  },
}

</script>

<style>

</style>

Answer №1

When reviewing your code, I noticed several areas that could be improved.

  1. Instead of pushing the response array into the existing recent_posts array, consider setting recent_posts = response.data directly. This way, you avoid unnecessary nesting.
  2. It's uncommon to define an EventBus handler within a watcher. It's best practice to set up such handlers in the created or mounted lifecycle hooks.
  3. Ensure that this inside the EventBus handler points to the Vue instance by binding the method to the component like so:
    EventBus.$on("addPost", this.addPost)
    .
  4. After making these improvements, adding a new post should be straightforward with this.recent_posts.push(newPost).

Here are some suggestions:

export default {
  name: 'RecentUpdates',
  data(){
    return {
      errors: [],
      recent_posts: []
    }
  },
  props: ['categories', 'user'],
  components: {
    PostList,
    PostFilter,
    Pagination
  },
  created() {
    if (this.user.meta.selected_categories[0] == 0) {
      this.showAllPosts();
    }
    this.getSelectedCategory();

    EventBus.$on("addPost", this.addPost)
  },
  beforeDestroy(){
    EventBus.$off("addPost", this.addPost)
  },
  methods: {
    getPosts(url){
      axios.get(url, {headers: {'X-WP-Nonce': portal.nonce}})
        .then(response => this.recent_posts = response.data)
        .catch(e => this.errors.push(e))
    },
    showAllPosts() {
      const url = '/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]';
      this.getPosts(url);
    },
    getSelectedPosts(categoryId) {
      const url = '/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&categories=' + categoryId;
      this.getPosts(url);     
    },     
    addPost(newPost){
      this.recent_posts.push(newPost)
    },
    ... //other methods
  },
}

Answer №2

Consider using kebab-case in your event listeners rather than camelCase:

  1. For example, v-on:selectedCategory="getSelectedPosts" should be v-on:selected-category="getSelectedPosts".
  2. Another example is v-on:showAllPosts="showAllPosts" should be v-on:show-all-posts="showAllPosts" or you can even use the shortcut @show-all-posts="showAllPosts".

UPDATE: If possible, please provide the code for the other components so we can better understand your issue. If you want to track changes in an object or array in vue.js, you will need to deep watch them. Your watcher should be:

 watch: {
    recent_posts: {
       deep: true,
       handler: function( oldValue, newValue) {
          console.log( "recent_posts has changed" );
          // A post has been added, updated, or deleted
       }
    }
 }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular allows you to retrieve values from localStorage

I have been trying to solve this issue by looking at various examples, but haven't been able to figure it out. In my Ionic app, I have a contact form that allows users to contact a listing owner. After the form submission, I want to store the ad id i ...

Retrieving Records within a Specific Date Range for Check-ins and Check-outs

Our team is currently working on developing booking software that requires handling different room pricing based on specific dates. Each room has distinct pricing for weekdays and weekends. ROOM 1 Pricing 1: September 1st - November 3rd, Weekday: $100, W ...

Vue: Detecting Change in Checked State and Triggering an Ajax Request

I am currently utilizing Bootstrap Vue: <b-form-checkbox @change="onoff('concurency_filter')" v-model="concurency_filter.onoff" switch size="lg"></b-form-checkbox> I need to make an ajax call based on the state of this checkbox: o ...

What is the significance of the expression $location.path() equal to '/a' in Angular?

I am currently delving into AngularJs for the first time and I have been studying the Angular documentation in order to grasp its concepts. While going through it, I came across this piece of code: $location.path() == '/a'. However, I am struggli ...

What sets apart `Object.merge(...)` from `Object.append(...)` in MooTools?

This question may seem simple at first glance, but upon further inspection, the MooTools documentation for the 'append' and 'merge' methods appears to be identical. Here is the code snippet provided in the documentation: var firstObj ...

Challenges encountered when using random values in Tailwind CSS with React

Having trouble creating a react component that changes the width based on a parameter. I can't figure out why it's not working. function Bar() { const p =80 const style = `bg-slate-500 h-8 w-[${p.toFixed(1)}%]` console.log(styl ...

Craft dynamic SVG components using TypeScript

Looking to generate a correctly formatted SVG element using TypeScript: createSVGElement(tag) { return document.createElementNS("http://www.w3.org/2000/svg", tag); } Encountering an issue with tslint: Error message: 'Forbidden http url in str ...

Creating a three-dimensional shape using a transparent image in Three.js

Hey there! I'm currently working on creating a 3D model that features the upper and lower sides as transparent images, while the other sides are a solid color (yellow in this case). var texture = new THREE.TextureLoader().load( 'img.png' ); ...

What could be causing req.body to consistently come back as an empty object?

I am struggling with req.body always returning an empty object regardless of what I try. I have experimented with: var jsonParser = bodyParser.json(); and then including jsonParser in the function -> app.post('/api/get-last-project',jsonPar ...

Having trouble with state not updating correctly after making a fetch request within a useEffect hook in

In my React app with an Express backend, I am facing a challenge in updating the component state using the useEffect hook to trigger once when the component renders. Inside the useEffect, I fetch data from the Express server. const Favorites = ({ user }) = ...

Transferring a variable between a JavaScript function and a Java class

Currently, I am working with STS and building an application that includes HTML files and JavaScript. Within this file, there is a function that configures variables. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www ...

Ajax failing to trigger upon submission

I need assistance in creating a form that will first submit via AJAX before directing to a specified URL. Once submitted, an email should be sent to me through newsletter.php <script type='text/javascript'> $(function () { $("#signup") ...

Controlling the document object model of a third-party website within the Electron framework

I am completely new to electron. My main goal is to load a URL and then execute some Javascript that will make changes to the DOM. Currently, my approach involves creating a BrowserWindow that loads the URL, and I understand that I can utilize webContents ...

Can you explain the concept of themes in Material UI?

I am trying to wrap my head around the concept of themes and what they are meant to represent. I have gone through the documentation, but I still find it confusing. For instance, here is a snippet of code that I am referring to. I just want to understand ...

Is there a way to update my profile picture without having to constantly refresh the page after uploading it?

Here is the code for my profile page. I am considering using a callback along with another useEffect function, but I'm unsure. Please help me in finding a solution. For now, let's ignore all the code related to deleting, saving, and handling ingr ...

What is the best way to use Promise.all() to delay the return of an array that is currently being constructed within the function?

In the following code block, I am trying to set an array as the value for a local variable by calling a function that returns an array. The issue arises because the Promises in the second function are not resolved until after the array has been returned to ...

Double injection of Redux-saga

I've encountered a strange issue with my redux-saga - it's being called twice instead of just once. Here is the action that triggers the saga: export function createRequest (data) { return { type: CREATE_REQUEST, payload: {data} }; ...

Executing a JavaScript function within the HTML body and passing a variable as an argument to the function

I recently created the following HTML code: <html> <title> Upload Infected File </title> <body> <header id = "header"> <h1 align="center">Upload Malware File</h1> <p align="center"> Pleas ...

Are you trying to uncover the secrets of slot machines?

I have a vue template with the following structure: <ul> <li>slide a</li> <li>slide b</li> .... </ul> However, I would like to pass in each slide from the parent component using a slot, like this: <caro ...

Decipher the communications sent by the server

I have been working on a hybrid application using vuejs and ruby on rails, and I am trying to figure out how to translate the error messages that are generated by the server. While I have managed to translate the titles easily with a method, I am strugglin ...