Vue Dynamic component is not been re rendered










0















I have a basic component for all my input fields that wraps a dynamic component.



<my-input v-model="book_id" as="select" :options="availableBooks"
label="Books" :dirty="changed.includes('book_id')"/>


I use a computed property to feed that component.



availableBooks () 
if(this.books.length === 0)
return [id: '1', text: 'test1']
else
return [id: '2', text: 'test2']




Inside my-input component, I render dynamically a component /my-input.vue



<template>
<div class="live-input" :class="cssClass">
<component :is="inputType" :state="currentState" :value="value" :errors="errors"
v-on="$listeners" v-bind="$attrs" class="d-inline-block"/>
</div>
</template>

props:
as: type: String, default: 'text' ,
label: type: String ,
hint: type: String ,
inline: type: Boolean, default: false ,
,

data()
return TextInput,
currentDirty: this.dirty,
selfUpdate: false,




Then I have a second component select select-input.vue



<template>
<b-select :value="value" @input="$emit('input', $event)"
ref="input" :state="state" :options="optionsForSelect"/>
</template>

props:
options: type: Array ,
,

data()
const sampleOption = this.options[0]
const valueMethod = tryProperties(sampleOption, ['value', 'id'])
const textMethod = tryProperties(sampleOption,
['text', 'name', 'label', 'toS']
)

return
localOptions: this.options,
optionsForSelect: this.options.map(option =>
if (typeof option === 'string')
return value: option, text: option
else
return value: option[valueMethod], text: option[textMethod]

),

,


First this.books.length equals to zero, then I updated async and it has some entries, When I trace the availableBooks object seems that is been updated correctly but the select dropdown is not been updated.



Also seems that prop options has been updated but still the component is not been rerendered.



watch: 
options: function(newVal, oldVal) // [id: '2', text: 'test2']
console.log('Prop changed: ', newVal, '
,









share|improve this question




























    0















    I have a basic component for all my input fields that wraps a dynamic component.



    <my-input v-model="book_id" as="select" :options="availableBooks"
    label="Books" :dirty="changed.includes('book_id')"/>


    I use a computed property to feed that component.



    availableBooks () 
    if(this.books.length === 0)
    return [id: '1', text: 'test1']
    else
    return [id: '2', text: 'test2']




    Inside my-input component, I render dynamically a component /my-input.vue



    <template>
    <div class="live-input" :class="cssClass">
    <component :is="inputType" :state="currentState" :value="value" :errors="errors"
    v-on="$listeners" v-bind="$attrs" class="d-inline-block"/>
    </div>
    </template>

    props:
    as: type: String, default: 'text' ,
    label: type: String ,
    hint: type: String ,
    inline: type: Boolean, default: false ,
    ,

    data()
    return TextInput,
    currentDirty: this.dirty,
    selfUpdate: false,




    Then I have a second component select select-input.vue



    <template>
    <b-select :value="value" @input="$emit('input', $event)"
    ref="input" :state="state" :options="optionsForSelect"/>
    </template>

    props:
    options: type: Array ,
    ,

    data()
    const sampleOption = this.options[0]
    const valueMethod = tryProperties(sampleOption, ['value', 'id'])
    const textMethod = tryProperties(sampleOption,
    ['text', 'name', 'label', 'toS']
    )

    return
    localOptions: this.options,
    optionsForSelect: this.options.map(option =>
    if (typeof option === 'string')
    return value: option, text: option
    else
    return value: option[valueMethod], text: option[textMethod]

    ),

    ,


    First this.books.length equals to zero, then I updated async and it has some entries, When I trace the availableBooks object seems that is been updated correctly but the select dropdown is not been updated.



    Also seems that prop options has been updated but still the component is not been rerendered.



    watch: 
    options: function(newVal, oldVal) // [id: '2', text: 'test2']
    console.log('Prop changed: ', newVal, '
    ,









    share|improve this question


























      0












      0








      0








      I have a basic component for all my input fields that wraps a dynamic component.



      <my-input v-model="book_id" as="select" :options="availableBooks"
      label="Books" :dirty="changed.includes('book_id')"/>


      I use a computed property to feed that component.



      availableBooks () 
      if(this.books.length === 0)
      return [id: '1', text: 'test1']
      else
      return [id: '2', text: 'test2']




      Inside my-input component, I render dynamically a component /my-input.vue



      <template>
      <div class="live-input" :class="cssClass">
      <component :is="inputType" :state="currentState" :value="value" :errors="errors"
      v-on="$listeners" v-bind="$attrs" class="d-inline-block"/>
      </div>
      </template>

      props:
      as: type: String, default: 'text' ,
      label: type: String ,
      hint: type: String ,
      inline: type: Boolean, default: false ,
      ,

      data()
      return TextInput,
      currentDirty: this.dirty,
      selfUpdate: false,




      Then I have a second component select select-input.vue



      <template>
      <b-select :value="value" @input="$emit('input', $event)"
      ref="input" :state="state" :options="optionsForSelect"/>
      </template>

      props:
      options: type: Array ,
      ,

      data()
      const sampleOption = this.options[0]
      const valueMethod = tryProperties(sampleOption, ['value', 'id'])
      const textMethod = tryProperties(sampleOption,
      ['text', 'name', 'label', 'toS']
      )

      return
      localOptions: this.options,
      optionsForSelect: this.options.map(option =>
      if (typeof option === 'string')
      return value: option, text: option
      else
      return value: option[valueMethod], text: option[textMethod]

      ),

      ,


      First this.books.length equals to zero, then I updated async and it has some entries, When I trace the availableBooks object seems that is been updated correctly but the select dropdown is not been updated.



      Also seems that prop options has been updated but still the component is not been rerendered.



      watch: 
      options: function(newVal, oldVal) // [id: '2', text: 'test2']
      console.log('Prop changed: ', newVal, '
      ,









      share|improve this question
















      I have a basic component for all my input fields that wraps a dynamic component.



      <my-input v-model="book_id" as="select" :options="availableBooks"
      label="Books" :dirty="changed.includes('book_id')"/>


      I use a computed property to feed that component.



      availableBooks () 
      if(this.books.length === 0)
      return [id: '1', text: 'test1']
      else
      return [id: '2', text: 'test2']




      Inside my-input component, I render dynamically a component /my-input.vue



      <template>
      <div class="live-input" :class="cssClass">
      <component :is="inputType" :state="currentState" :value="value" :errors="errors"
      v-on="$listeners" v-bind="$attrs" class="d-inline-block"/>
      </div>
      </template>

      props:
      as: type: String, default: 'text' ,
      label: type: String ,
      hint: type: String ,
      inline: type: Boolean, default: false ,
      ,

      data()
      return TextInput,
      currentDirty: this.dirty,
      selfUpdate: false,




      Then I have a second component select select-input.vue



      <template>
      <b-select :value="value" @input="$emit('input', $event)"
      ref="input" :state="state" :options="optionsForSelect"/>
      </template>

      props:
      options: type: Array ,
      ,

      data()
      const sampleOption = this.options[0]
      const valueMethod = tryProperties(sampleOption, ['value', 'id'])
      const textMethod = tryProperties(sampleOption,
      ['text', 'name', 'label', 'toS']
      )

      return
      localOptions: this.options,
      optionsForSelect: this.options.map(option =>
      if (typeof option === 'string')
      return value: option, text: option
      else
      return value: option[valueMethod], text: option[textMethod]

      ),

      ,


      First this.books.length equals to zero, then I updated async and it has some entries, When I trace the availableBooks object seems that is been updated correctly but the select dropdown is not been updated.



      Also seems that prop options has been updated but still the component is not been rerendered.



      watch: 
      options: function(newVal, oldVal) // [id: '2', text: 'test2']
      console.log('Prop changed: ', newVal, '
      ,






      vue.js






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 13 '18 at 13:10







      Petran

















      asked Nov 13 '18 at 13:01









      PetranPetran

      2,705123962




      2,705123962






















          2 Answers
          2






          active

          oldest

          votes


















          1














          If you want to get updates for the options prop in order to re-render your component when options changes, you should use a computed attribute for optionsForSelect instead of a data one. When using data the value gets copied in the component and will only get re-rendered when the data attribute is changed locally.



          If you use a computed property, when the parent component changes the prop options value, the computed attribute will get re-evaluated and your component will render again.



          computed: 
          optionsForSelect()
          if (typeof option === 'string')
          return value: option, text: option
          else
          return value: option[valueMethod], text: option[textMethod]





          The computed property would be my preferred approach.



          However, you can also accomplish this with the data attribute you have. You would have to add a watcher for the options prop and assign the new value each time the prop is updated to optionsForSelect data attribute.



          watch: 
          options: function(newVal, oldVal)
          // Update this.optionsForSelect value here




          Hope it helps.






          share|improve this answer






























            0














            Once that have entered the WATCH function, you can update the select-input view with this.$forceUpdate().



            watch: 
            options: function(newVal, oldVal) // [id: '2', text: 'test2']
            // console.log('Prop changed: ', newVal, '






            share|improve this answer























            • Tried that but didn't work

              – Petran
              Nov 13 '18 at 14:44










            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53281595%2fvue-dynamic-component-is-not-been-re-rendered%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            If you want to get updates for the options prop in order to re-render your component when options changes, you should use a computed attribute for optionsForSelect instead of a data one. When using data the value gets copied in the component and will only get re-rendered when the data attribute is changed locally.



            If you use a computed property, when the parent component changes the prop options value, the computed attribute will get re-evaluated and your component will render again.



            computed: 
            optionsForSelect()
            if (typeof option === 'string')
            return value: option, text: option
            else
            return value: option[valueMethod], text: option[textMethod]





            The computed property would be my preferred approach.



            However, you can also accomplish this with the data attribute you have. You would have to add a watcher for the options prop and assign the new value each time the prop is updated to optionsForSelect data attribute.



            watch: 
            options: function(newVal, oldVal)
            // Update this.optionsForSelect value here




            Hope it helps.






            share|improve this answer



























              1














              If you want to get updates for the options prop in order to re-render your component when options changes, you should use a computed attribute for optionsForSelect instead of a data one. When using data the value gets copied in the component and will only get re-rendered when the data attribute is changed locally.



              If you use a computed property, when the parent component changes the prop options value, the computed attribute will get re-evaluated and your component will render again.



              computed: 
              optionsForSelect()
              if (typeof option === 'string')
              return value: option, text: option
              else
              return value: option[valueMethod], text: option[textMethod]





              The computed property would be my preferred approach.



              However, you can also accomplish this with the data attribute you have. You would have to add a watcher for the options prop and assign the new value each time the prop is updated to optionsForSelect data attribute.



              watch: 
              options: function(newVal, oldVal)
              // Update this.optionsForSelect value here




              Hope it helps.






              share|improve this answer

























                1












                1








                1







                If you want to get updates for the options prop in order to re-render your component when options changes, you should use a computed attribute for optionsForSelect instead of a data one. When using data the value gets copied in the component and will only get re-rendered when the data attribute is changed locally.



                If you use a computed property, when the parent component changes the prop options value, the computed attribute will get re-evaluated and your component will render again.



                computed: 
                optionsForSelect()
                if (typeof option === 'string')
                return value: option, text: option
                else
                return value: option[valueMethod], text: option[textMethod]





                The computed property would be my preferred approach.



                However, you can also accomplish this with the data attribute you have. You would have to add a watcher for the options prop and assign the new value each time the prop is updated to optionsForSelect data attribute.



                watch: 
                options: function(newVal, oldVal)
                // Update this.optionsForSelect value here




                Hope it helps.






                share|improve this answer













                If you want to get updates for the options prop in order to re-render your component when options changes, you should use a computed attribute for optionsForSelect instead of a data one. When using data the value gets copied in the component and will only get re-rendered when the data attribute is changed locally.



                If you use a computed property, when the parent component changes the prop options value, the computed attribute will get re-evaluated and your component will render again.



                computed: 
                optionsForSelect()
                if (typeof option === 'string')
                return value: option, text: option
                else
                return value: option[valueMethod], text: option[textMethod]





                The computed property would be my preferred approach.



                However, you can also accomplish this with the data attribute you have. You would have to add a watcher for the options prop and assign the new value each time the prop is updated to optionsForSelect data attribute.



                watch: 
                options: function(newVal, oldVal)
                // Update this.optionsForSelect value here




                Hope it helps.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 13 '18 at 18:08









                AndresAndres

                33538




                33538























                    0














                    Once that have entered the WATCH function, you can update the select-input view with this.$forceUpdate().



                    watch: 
                    options: function(newVal, oldVal) // [id: '2', text: 'test2']
                    // console.log('Prop changed: ', newVal, '






                    share|improve this answer























                    • Tried that but didn't work

                      – Petran
                      Nov 13 '18 at 14:44















                    0














                    Once that have entered the WATCH function, you can update the select-input view with this.$forceUpdate().



                    watch: 
                    options: function(newVal, oldVal) // [id: '2', text: 'test2']
                    // console.log('Prop changed: ', newVal, '






                    share|improve this answer























                    • Tried that but didn't work

                      – Petran
                      Nov 13 '18 at 14:44













                    0












                    0








                    0







                    Once that have entered the WATCH function, you can update the select-input view with this.$forceUpdate().



                    watch: 
                    options: function(newVal, oldVal) // [id: '2', text: 'test2']
                    // console.log('Prop changed: ', newVal, '






                    share|improve this answer













                    Once that have entered the WATCH function, you can update the select-input view with this.$forceUpdate().



                    watch: 
                    options: function(newVal, oldVal) // [id: '2', text: 'test2']
                    // console.log('Prop changed: ', newVal, '







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 13 '18 at 14:17









                    javimovijavimovi

                    318110




                    318110












                    • Tried that but didn't work

                      – Petran
                      Nov 13 '18 at 14:44

















                    • Tried that but didn't work

                      – Petran
                      Nov 13 '18 at 14:44
















                    Tried that but didn't work

                    – Petran
                    Nov 13 '18 at 14:44





                    Tried that but didn't work

                    – Petran
                    Nov 13 '18 at 14:44

















                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53281595%2fvue-dynamic-component-is-not-been-re-rendered%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Barbados

                    How to read a connectionString WITH PROVIDER in .NET Core?

                    Node.js Script on GitHub Pages or Amazon S3