Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

richcfml's avatar

Uncaught TypeError: Cannot read property 'post' of undefined

While going thru the tutorial for payments with Laravel and stripe I am getting the error above when trying to submit the form in the Vue template. Below is the template and the line this.$http.post('payments/checkout', this.$data) .then(response => alert('Thank you for your purchase!.')); is where I get the error. I have checked that Vue and vue-resource are installed and they seem to be. Any ideas will be appreciated it.

  <form class="form-horizontal" role="form" method="POST" action="payments/checkout">


    <input type="hidden" name="stripeToken" v-model="stripeToken" />
    <input type="hidden" name="stripeEmail" v-model="stripeEmail" />

    <div class="form-group">
      <div class="col-md-8">
        <label> Select New Plan</label>
        <select name="plan" v-model="plan" class="form-control col-md-8" >
          <option v-for="plan in plans" :value="plan.id">
            {{ plan.name }} - ${{ plan.price / 100}}
          </option>
        </select>
      </div>
    </div>
    <div class="form-group">
      <div class="col-md-8">
        <button type="submit" class="btn btn-primary" @click.prevent="buy">Proceed to Payment</button>
        <a class="btn btn-default" href="/myaccount">Cancel</a>
      </div>
    </div>
  </form>
</template>

<script>
    export default {

      props: ['plans'],
      data() {
          return{
            stripeEmail: '',
            stripeToken: '',
            plan: 2
          };
      },

      created(){
        this.stripe = StripeCheckout.configure({
            key: Sadmin.stripeKey,
            image: "https://stripe.com/img/documentation/checkout/marketplace.png",
            locale: "auto",
            token: function(token){
              this.stripeEmail = token.email;
              this.stripeToken = token.id;

              this.$http.post('payments/checkout', this.$data)
                  .then(response => alert('Thank you for your purchase!.'));

            }
          });
      },

      methods: {

        buy(){

          let plan = this.findPlanById(this.plan);

          this.stripe.open({
            name: plan.name,
            description: plan.description,
            zipCode: true,
            amount: plan.price
          });
        },

        findPlanById(id){
          return this.plans.find(plan => plan.id == id);
        }

      }

    };
</script>```
0 likes
8 replies
lara12664's avatar

Can you post your main.js or whatever it is named? Where vue-resource is setup.

As it can't find a post method on the object, I would think the error is with linking Vue and vue-resource.

richcfml's avatar

Sure here it is.



/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides support
 * for JavaScript based Bootstrap features such as modals and tabs. This
 * code may be modified to fit the specific needs of your application.
 */

window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');

/**
 * Vue is a modern JavaScript library for building interactive web interfaces
 * using reactive data binding and reusable components. Vue's API is clean
 * and simple, leaving you to focus on building your next great project.
 */

window.Vue = require('vue');
Vue.use(require('vue-resource'));


/**
 * We'll register a HTTP interceptor to attach the "CSRF" header to each of
 * the outgoing requests issued by this application. The CSRF middleware
 * included with Laravel will automatically verify the header's value.
 */

Vue.http.interceptors.push((request, next) => {
    request.headers.set('X-CSRF-TOKEN', SIGadmin.csrfToken);
    
    next();
});


richcfml's avatar

I removed JQuery and bootstrap and changed the line

Vue.use(require('vue-resource'));

to just

require('vue-resource');

and double checked that the package.json file has the vue-resource loaded and ran npm install as well as composer update.

However, I am still getting the same error as if vue-resource is not loaded at all. I also try to create a get request and did not work either, making me certain that the issue is with the load of vue-resource.

if anyone has any ideas I will appreciate the help

n1ch0la5's avatar

Did you ever figure it out? I'm having the same problem.

jurjen's avatar

Every function has its own this value, so this.$http doesn't exist inside your token function. Use an arrow function to not bind this to a new value:

token: (token) => {
    this.stripeEmail = token.email;
    this.stripeToken = token.id;
    
    this.$http.post('payments/checkout', this.$data)
                  .then(response => alert('Thank you for your purchase!.'));

}
1 like
prashant.godhwani's avatar

Hey, I am having the same error over here `

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Upload Video</div>

                    <div class="panel-body">
                        <input type="file" name="video" id="video" @change="fileInputChange" v-if="!uploading">
                        <div id="video-form" v-if="uploading && !failed">
                            form

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

<script>
    export default {
        data(){
            return{
                uploading:false,
                uploadingComplete:false,
                failed:false,
                title:'untitled',
                description:null,
                visibility:'private',
            }
        },
        methods:{
            fileInputChange(){
                this.uploading = true;
                this.failed = false;
                this.file=document.getElementById('video').files[0];
                this.store().then(()=>{
                    //upload the video
                })
            },
            store(){
                return this.$http.post('/videos', {
                    title: this.title,
                    description: this.description,
                    visibility: this.visibility,
                    extension: this.file.name.split('.').pop()
                }).then((response)=>{
                    console.log(response.json());
                });
            }
        },
        mounted() {

        }
    }
</script>

`

Please help me ! :)

dannys's avatar

@prashant.godhwani You are using export default script, therefore your this keyword, does not have access to the Vue instance original module, but to an imported object component. The most likely scenario is that with require, vue-resource is only available to that original module, so you should use import VueResource from "vue-resource", this way, with the es6 syntax the vue-resource library is hoisted with an internal module, before it is evaluated and cached on the browser with the alongside the Vue instance@jurjen has stated a similar constraint, where the this keyword is not pointing at Vue. Another alternative would be to use the Vue instance itself instead of exportin a default object. Check out http://voidcanvas.com/import-vs-require/ you can probably get more out of it than i did.

Please or to participate in this conversation.