0

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 :)

3
  • this.errors.push(e) is where the error is, you never define errors in data() Commented Jan 7, 2019 at 21:24
  • @derek Pollard i also missed that out. But the error is from the line this.speakers.push(speaker) Commented Jan 7, 2019 at 21:53
  • Checkout my answer and let me know if it fixes your problem Commented Jan 7, 2019 at 22:37

1 Answer 1

1

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!

Sign up to request clarification or add additional context in comments.

1 Comment

Hey @derek Pollard although your input didn't solve my problem, it made me gave me an 'AHA' moment to different ways you could go about emiting :) everything was reaching to where it needed to go, but it was the data that was being imported was incorrect, as the shape of the data had changed, i wasn't getting the right set, hence it was undefined!! I just came back after the Christmas break, must still be holiday. rookie mistake! just goes to show you really do need to check every angle, even if you think you did! this is my first app using vue, seems v handy :) thanks for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.