Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component modal props won't update #533

Closed
njanke96 opened this issue Jan 16, 2018 · 6 comments

Comments

Projects
None yet
4 participants
@njanke96
Copy link

commented Jan 16, 2018

Overview of the problem

Buefy version: 0.6.2
Vuejs version: 2.3.3
OS/Browser: Linux/Chromium (electron)

Description

I'm trying to use a component modal to show progress of a task, I can't seem to update my progress property to update the progress bar. This is more likely not a bug but rather me using the props option correctly.

Steps to reproduce

I have an EventEmitter (BSPFile) emitting a progress event when progress is made during a lengthy operation. The progress property within the ProgressModal component is bound to the value of my progress bar.

// load bsp
  const bspFile = new BSPFile()

  // progress modal
  let modalProps = {
    title: `Loading ${vm.fileName} ...`,
    message: `Loading BSP data...`,
    progress: 0
  }

  vm.$modal.open({
    parent: vm,
    component: ProgressModal,
    hasModalCard: true,
    canCancel: false,
    props: modalProps
  })

  bspFile.on('loadProgress', (progress) => {
    console.log(progress)
    modalProps.progress = progress
  })

  // load bsp data
  await bspFile.load(filePath)
  bspFile.removeAllListeners('loadProgress')

ProgressModal.vue:

<template>
  <div class="modal-card">
    <header class="modal-card-head">
      <p class="modal-card-title">{{ title }}</p>
    </header>

    <section class="modal-card-body">
      <div class="container is-fluid">
        <h6 class="subtitle is-6">{{ message }}</h6>
        <progress class="progress is-primary" :value="progress" max="100"></progress>
      </div>
    </section>

  </div>
</template>

<script>
export default {
  name: 'ProgressModal',
  props: {
    title: {
      type: String,
      required: true
    },
    message: {
      type: String,
      required: true
    },
    progress: {
      type: Number,
      required: true
    }
  }
}
</script>

Expected behavior

The progress property updates and the bound progress prop 'value' changes.

Actual behavior

The bound progress prop 'value' does not change. I know the event fires because the console.log works.

@vinczebalazs

This comment has been minimized.

Copy link

commented Dec 25, 2018

I am having the exact same issue, the passed in props seem to lose their reactivity.

@PayteR

This comment has been minimized.

Copy link

commented Jan 5, 2019

I want to acheive something similar, my solution is to update whole props param, in your case it would be something like this:

const bspFile = new BSPFile()

// progress modal
let modalProps = {
  title: `Loading ${vm.fileName} ...`,
  message: `Loading BSP data...`,
  progress: 0
}

let modalInstance = vm.$modal.open({
  parent: vm,
  component: ProgressModal,
  hasModalCard: true,
  canCancel: false,
  props: modalProps
})

bspFile.on('loadProgress', (progress) => {
  modalProps.progress = progress
  modalInstance.props = modalProps
})

// load bsp data
await bspFile.load(filePath)
bspFile.removeAllListeners('loadProgress')

It works, BUT it gives me this warning

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "props"

found in

---> <BModal>
       <Root>

It would be great to have some interface o update props

@jtommy

This comment has been minimized.

Copy link
Member

commented Jan 5, 2019

@PayteR @njanke96 @vinczebalazs Did you try to call $forceUpdate after props update ?
For example:

const bspFile = new BSPFile()

// progress modal
let modalProps = {
  title: `Loading ${vm.fileName} ...`,
  message: `Loading BSP data...`,
  progress: 0
}

let modalInstance = vm.$modal.open({
  parent: vm,
  component: ProgressModal,
  hasModalCard: true,
  canCancel: false,
  props: modalProps
})

bspFile.on('loadProgress', (progress) => {
  modalProps.progress = progress
  modalInstance.$forceUpdate()
})

// load bsp data
await bspFile.load(filePath)
bspFile.removeAllListeners('loadProgress')
@PayteR

This comment has been minimized.

Copy link

commented Jan 5, 2019

@jtommy this is maybe solution for @njanke96, but in my case i need to update whole props parameter in my instantiated modal component. When i update props modalInstance.props = modalProps it works, but i get warning, is there solution for me how update props with "correct way"?

@jtommy

This comment has been minimized.

Copy link
Member

commented Jan 5, 2019

If you try my code all props will be updated (all fields in modalProps) without set it to modal instance.

@PayteR

This comment has been minimized.

Copy link

commented Jan 7, 2019

@jtommy ok i tried to rewrite that i update every props key and then $forceUpdate like this

Object.keys(props).forEach((key) => {
   modalInstance .props[key] = props[key]
})
modalInstance .$forceUpdate()

no warning messages now, little messy but it's good enough, thx

@jtommy jtommy closed this Jan 7, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.