matt mcgregor
matt mcgregor

Reputation: 11

Trying to push data to an array from a child component in vue.js but get TypeError: Cannot read property 'push' of undefined"

here is my child component

<b-container fluid class="bv-example-row">
        <b-row>
            <b-col cols="2" class="col-speaker">
                <b-row>
                    <b-input-group @keyup.enter="speakerInput" class="input-speaker">
                        <b-form-input  v-model="speaker" placeholder="speaker"></b-form-input>
                    </b-input-group>
                    {{speaker}}
                    <div class="w-100"></div>
                    <b-col>
                        <img class="caption-flag" src="../assets/flag (2).png">
                    </b-col>
                </b-row>
            </b-col>
            <b-col>
                <div class="mainDashboard-caption">

                <h4 class="caption-timecode">{{start}}-{{end}}</h4>
                <b-row>
                    <b-col cols="11">
                        <b-form-textarea id="textarea1"
                                        v-model="userInput"
                                        placeholder="Enter something"
                                        :rows="3"
                                        :max-rows="6">
                        </b-form-textarea> 
                    </b-col>
                    <b-col>
                        <input class="caption-reviewed" type="checkbox"> 
                    </b-col>
                </b-row>

                <b-row class="row-buttons">
                    <b-col class="col-buttons">
                        <b-button :pressed="false" variant="outline-success" class="caption-merge-next">merge next</b-button>
                        <b-button :pressed="false" variant="outline-danger" class="caption-merge-prev">merge prev </b-button>
                    </b-col>
                </b-row>
                </div>
            </b-col>
        </b-row>
    </b-container>
</template>

<script>
export default {
    name: 'MainDashboard',
    props: {
        start: { type: Number, required: true},
        end: { type: Number, required: true},
        text: '',
    },

    data () {
        return {
            userInput: '',
            speaker: '',
            plainText: false,
        }
    },

    methods: {
        speakerInput (speaker) {
        console.log(speaker)
            this.$emit('post-speaker', speaker)

        }

    }



}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

and here is my parent

<template>
    <div class="dashboardView">
        <div class="header">
            <MainHeader
            v-bind:fileName= this.fileName
            />
        </div>
        <div class="dashboard" v-for='caption in captions' :key='caption.end'>
            <MainDashboard 
            v-bind:start='caption.start'
            v-bind:end='caption.end' 
            v-bind:text='caption.text'

            @post-speaker="postSpeaker"                       
            />
        </div>
        <div class="footer">

        </div>
    </div>
</template>

<script>
// @ is an alias to /src
import axios from 'axios'

import MainHeader from '../components/MainHeader.vue';
import MainDashboard from '../components/MainDashboard.vue';

export default { 
  name: 'dashboard',
  components: {
      MainDashboard,
  },
  data () {
    return {
      speakers: [],
      speaker:'',
      captions: [],
      text: '',
      fileName: '',
      result: this.getCookie('csrftoken')

    }

  },
  methods: {

    getCookie(key) {
      const regexp = new RegExp(`.*${key}=([^;]*)`);
      const result = regexp.exec(document.cookie);
      if(result) {
        return result [1]
      }
    },
    postSpeaker(speaker) {
      console.log(speaker)
      this.speakers.push(speaker)
      console.log(this.speakers)
      this.getCookie('csrftoken')
      axios.put('https://172.28.128.13/api/transcriptions/1/',{
          captions: {
            speakers: [this.speakers], captions: [this.captions]
          }
      },
       { 
         headers: {
            'X-CSRFToken': this.result} 
        }) 
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
    },
  },

  created() {
    axios.get(`https://172.28.128.13/api/transcriptions/?format=json`)
    .then(response => {
      // JSON responses are automatically parsed.
      this.captions = response.data.results[0].captions
      this.fileName = response.data.results[0].media_file
      this.speakers = response.data.results[0].captions.speakers
      console.log(this.fileName)
      console.log(this.captions)
    })
    .catch(e => {
      this.errors.push(e)
    })
  },
  components: {
    MainHeader,
    MainDashboard,
  },
};
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

im trying to emit the users input data in the child component to the parent component, and push it into speakers array. it breaks on this.speakers.push(speaker)in the parent component, and i get this error

[Vue warn]: Error in event handler for "post-speaker": "TypeError: Cannot read property 'push' of undefined"

Im sure its something little that i'm doing wrong, any help is appreciated :)

Upvotes: 0

Views: 468

Answers (1)

Derek Pollard
Derek Pollard

Reputation: 7165

Your problem is in the child component:

@keyup.enter="speakerInput"

If you notice, speakerInput expects you to pass speaker to it so it can ultimately emit the event to the parent.

Change it to:

@keyup.enter="speakerInput(speaker)"

Or, change speakerInput to use the data instead of expecting it to be passed:

methods: {
    speakerInput () {
        console.log(this.speaker)
        this.$emit('post-speaker', this.speaker)
    }
}

Hope this helps!

Upvotes: 1

Related Questions