I have a front end application with a contact form for clients, and my goal is to be able to send emails from the form the client will fill out to the company startup email. For that , I already validated the form and my intention is to send back the information to my back end application (node.js) to send the email. The only problem is that form some reason on the vue.js webpack template, I get the Cannot POST error. So what I have tried so far was web sockets which didnt work because I cant seem to use the POST HTTP method, I also tried using vue-resource with the this.$http.post() method which didn't work either because I get the following error message:
Uncaught TypeError: Cannot read property 'post' of undefined
the following is my vue instance with the contact form :
<template>
<main id="fullpage">
<b-form @submit.prevent="validateForm($event)" id="contactForm" autocomplete="off">
<section class="section contactForm">
<b-form-row>
<h1>{{clientMsg}}</h1>
</b-form-row>
<b-form-row>
<b-col>
<input type="radio" name="client" value="individual" @click="IndvClient"> <label for="individual">an individual?</label>
</b-col>
<b-col>
<input type="radio" name="client" value="company" @click="CorporateClient" > <label for="company">a company?</label>
</b-col>
<b-col cols="12">
<a class="steps text-right next" :href="sectionLinks.emailLink">Next</a>
</b-col>
</b-form-row>
</section>
<section class="section contactForm">
<b-row no-gutters>
<b-col>
<input type="email" id="usrEmail" placeholder="Email address..." class="text-center"
:pattern="emailValidation" required v-model="email" @mouseout="isValidEmail($event)" autocomplete="off">
</b-col>
</b-row>
<b-row no-gutters>
<b-col cols="6">
<a href="#clientType" class="steps text-left">Previous</a>
</b-col>
<b-col cols="6">
<a class="steps text-right next" :href="sectionLinks.nameLink">Next</a>
</b-col>
</b-row>
</section>
<section class="section contactForm">
<input type="text" name="usrName" id="usrName" placeholder="Name..." class="text-center"
required :pattern="textValidation" v-model="name" @mouseout="isValidName($event)" autocomplete="off">
<b-row no-gutters>
<b-col cols="6">
<a href="#email" class="steps text-left">Previous</a>
</b-col>
<b-col cols="6">
<a class="steps text-right next" :href="sectionLinks.titleLink">Next</a>
</b-col>
</b-row>
</section>
<section class="section contactForm">
<input type="text" name="msgTitle" id="msgTitle" placeholder="Title of the message..."
class="text-center" v-model="messageTitle" required :pattern="textValidation"
@mouseout="isValidTitle($event)" autocomplete="off">
<b-row no-gutters>
<b-col cols="6">
<a href="#name" class="steps text-left">Previous</a>
</b-col>
<b-col cols="6">
<a class="steps text-right next" :href="sectionLinks.msgLink" >Next</a>
</b-col>
</b-row>
</section>
<section class="section contactForm">
<b-row no-gutters>
<b-col cols="12">
<textarea name="" id="msgContent" cols="100" rows="7"
placeholder="Message..." v-model="message" required
@mouseout="isValidMsg($event)"></textarea>
</b-col>
</b-row>
<b-row no-gutters>
<b-col cols="6">
<a href="#title" class="steps text-left">Previous</a>
</b-col>
<b-col cols="6">
<a class="steps text-right next" :href="sectionLinks.msgSummaryLink">Next</a>
</b-col>
</b-row>
</section>
<section class="section contactForm formSummary">
<ul class="prevFormLinks">
<li v-for="section in previousLinks">
<a :href="section.link">{{section.name}}</a>
</li>
</ul>
<b-form-row>
<p>{{clientMsg}}</p>
</b-form-row>
<b-form-row>
<b-col>
<input type="radio" name="userClient" value="individual"> <label for="individual">an individual?</label>
</b-col>
<b-col>
<input type="radio" name="userClient" value="company"> <label for="company">a company?</label>
</b-col>
</b-form-row>
<b-form-row>
<b-col>
<h2>Your email:</h2>
</b-col>
<b-col>
<p>{{email}}</p>
</b-col>
</b-form-row>
<b-form-row>
<b-col>
<h2>Name:</h2>
</b-col>
<b-col>
<p>{{name}}</p>
</b-col>
</b-form-row>
<b-form-row>
<b-col>
<h4>Title of the message:</h4>
</b-col>
<b-col>
<p>{{messageTitle}}</p>
</b-col>
</b-form-row>
<b-form-row>
<b-col cols="5" id="msgSummary">
<p>{{message}}</p>
</b-col>
</b-form-row>
<b-form-row>
<b-col cols="12">
<input type="submit" value="Submit!">
</b-col>
</b-form-row>
</section>
</b-form>
</main>
</template>
<script>
import fullpage from 'fullpage.js'
import $ from "jquery"
import VueResource from 'vue-resource';
/**
Make sure you can then send an email
Replace the jQuery animations with anime.js or another way of animating.
There are no previous buttons for the summary section.
*/
export default {
data(){
return {
"clientMsg":this.$store.state.contact.TypeOfClientMsg,
"name":"",
"email":"",
"messageTitle":"",
"message":"",
"emailValidation":"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$",
"textValidation":"[a-zA-Z ]+",
"sectionLinks":{
"clientLink":"#clientType",
"emailLink":"#email",
"nameLink": "#name",
"titleLink":"#title",
"msgLink":"#message",
"msgSummaryLink":"#messageSummary"
},
"previousLinks":[
{
"link":"#clientType",
"name":"Client"
},
{
"link":"#email",
"name":"Email"
},
{
"link":"#name",
"name":"Name"
},
{
"link":"#title",
"name":"Title"
},
{
"link":"#message",
"name":"Message"
}
],
"companyEmail":"salay777@hotmail.co.uk"
}
},
methods:{
IndvClient:function(){
let ind = document.querySelectorAll('input[value="individual"]');
let company = document.querySelectorAll('input[value="company"]'),
goToEmail = document.querySelector('a[href="#email"]');
(ind[0].checked == true)? ind[1].checked = true : ind[1].checked = false;
$(goToEmail).fadeIn();
},
CorporateClient:function(){
let ind = document.querySelectorAll('input[value="individual"]');
let company = document.querySelectorAll('input[value="company"]'),
goToEmail = document.querySelector('a[href="#email"]');
(company[0].checked == true)? company[1].checked = true : company[1].checked = false;
$(goToEmail).fadeIn();
},
isValidEmail:function(e){
let goToName = document.querySelector('a[href="#name"]');
(e.target.checkValidity())? $(goToName).fadeIn() : $(goToName).fadeOut();
},
isValidName:function(e){
let goToTitle = document.querySelector('a[href="#title"]');
(e.target.checkValidity())? $(goToTitle).fadeIn() : $(goToTitle).fadeOut();
},
isValidTitle:function(e){
let goToMsg = document.querySelector('a[href="#message"]');
(e.target.checkValidity())? $(goToMsg).fadeIn() : $(goToMsg).fadeOut();
},
isValidMsg:function(e){
let goToSummary = document.querySelector('a[href="#messageSummary"]');
(e.target.checkValidity())? $(goToSummary).fadeIn() : $(goToSummary).fadeOut();
},
validateForm:function(e){
let idvClient = document.querySelector('input[value="individual"]'),
corporateClient = document.querySelector('input[value="company"]'),
usrEmail = document.getElementById('usrEmail'), usrName = document.
getElementById('usrName'), msgTitle = document.getElementById('msgTitle'),
msgContent = document.getElementById('msgContent');
if(idvClient.checked !== corporateClient.checked){
console.log('client has been checked');
if(usrEmail.checkValidity() == false || usrName.checkValidity() == false ||
msgTitle.checkValidity() == false || msgContent.checkValidity() == false){
e.preventDefault();
} else {
let email = {
client :"",
email: this.email,
name: this.name,
title: this.messageTitle,
message: this.message
};
if(idvClient.checked){
email.client = "[IDV]";
}
if(corporateClient.checked){
email.client = "[CO]";
}
this.$http.post('http://localhost:5000', email).then((data)=>{
console.log('the data has been sent', data);
});
//socket.emit('email',email);
alert('submitted!');
}
} else {
console.log('you need to select a client type');
e.preventDefault();
}
}
},
mounted(){
let idvClient = document.querySelector('input[value="individual"]'),
corporateClient = document.querySelector('input[value="company"]'),
goToEmail = document.querySelector('a[href="#email"]'), form =
document.querySelector('form'); //, socket = io.connect('http://localhost:5000/');
form.setAttribute('autocomplete', 'off');
if(idvClient.checked == corporateClient.checked){
goToEmail.style.display = 'none';
}
}
};
</script>
<style>
html body #fullpage {
background-color:#383838 !important;
background-image: none !important;
}
html, body,#fullpage {
overflow: hidden !important;
}
.fp-tableCell{
text-align:center;
display:flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.contactDetails .row {
margin:0px;
}
.contactForm .form-row {
min-width:500px;
justify-content:center;
}
.contactForm .form-row a, .contactForm .row a {
margin: 60px;
text-decoration: none;
color: #f4f4f4;
font-size: 36px;
font-weight: 100;
transition: color .5s, font-size .2s;
}
.contactForm .form-row a:hover, .contactForm .row a:hover {
color:orange;
font-size:40px;
}
#menu {
display: none !important;
}
button {
margin-top:20px;
}
h1, h2, h3 , h4 {
font-weight:100;
}
.next {
display: none;
}
#msgSummary {
word-wrap: break-word;
text-align:left;
}
.formSummary, .formSummary h2 , .formSummary h4,
.formSummary p {
text-align:left !important;
}
.prevFormLinks {
position:absolute;
left:30px;
text-align:left;
margin:0px !important;
padding:0px;
color:white !important;
}
.prevFormLinks a {
font-size:20px !important;
margin:0px!important;
padding: 0px !important;
text-decoration: none;
color: white !important;
font-weight:100;
transition: font-size .25s, color 2s;
}
.prevFormLinks a:hover {
font-size: 25px !important;
color: orange !important;
}
</style>
the following is my main.js on the vue webpack template.
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import $ from "jquery"
import fullpage from 'fullpage.js'
import router from './router'
import store from './store'
import BootstrapVue from 'bootstrap-vue'
import Vuelidate from 'vuelidate'
import VueResource from 'vue-resource'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import './assets/css/style.css';
import 'owl.carousel/dist/assets/owl.carousel.min.css';
import 'owl.carousel/dist/assets/owl.theme.default.min.css';
Vue.config.productionTip = false
Vue.use(BootstrapVue);
Vue.use(Vuelidate);
Vue.use(VueResource);
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>',
router,
store
})
$(document).ready(()=>{
$('#fullpage').fullpage({
anchors:['clientType', 'email', 'name','title','message','messageSummary'],
keyboardScrolling:false,
fadingEffect: true,
scrollbar: false,
scrollOverflow: false,
autoScrolling:false,
menu:true
});
$.fn.fullpage.setMouseWheelScrolling(false);
$.fn.fullpage.setAllowScrolling(false);
});
the following is my back end application so far:
let express = require('express'), app = express(),
path = require('path'), bodyParser = require('body-parser'),
socket = require('socket.io'),urlencodedParser = bodyParser.urlencoded({ extended: false });
let server = app.listen(5000, ()=>{
console.log('listening to requests...');
});
let io = socket(server);
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
// io.on('connection', (socket)=>{
// console.log('made a connection!');
// socket.on('email', (data)=>{
// console.log(data);
// });
// });
app.post('http://localhost:5000', urlencodedParser,(req, res)=>{
console.log(req.body);
});
When I click on the submit button, what I want is to post the data to my back end in order to log what has been sent to the console for the time being. My final goal is to send an email.So far, this is the error message I am receiving:
Failed to load http://localhost:5000/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
Uncaught (in promise) Response