Using VueJS with Axios post response data disappears - javascript

I have been trying to figure out how to use VueJS, Axios and Python together. I can make a post request to the python file just fine. When I click the submit button, the response data shows correctly, but only for a second and then disappears. Why is this?
insert.py
#!/usr/bin/python3.6
import os
import sys
import json
parsed_json = json.loads(sys.stdin.read())
print ("Content-type: text/html\n")
print(parsed_json['firstName'])
print(parsed_json['lastName'])
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>index.html</title>
</head>
<body>
<form id="example-1">
<input type="text" ref="firstName">
<input type="text" ref="lastName">
<button v-on:click="submit">Submit</button>
{{ output }}
</form>
<script src="https://unpkg.com/vue#2.4.2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var example1 = new Vue({
el: '#example-1',
data: {
output: ''
},
methods: {
submit: function () {
axios.post('/cgi-bin/insert.py', {
firstName: this.$refs.firstName.value,
lastName: this.$refs.lastName.value
})
.then(response => {
this.output = response.data;
})
.catch(function (error) {
console.log(error);
});
}
}
})
</script>
</body>
</html>

Change your button to type="button".
<button type="button" v-on:click="submit">Submit</button>
The default button type is "submit" which results in a refresh of your page.
Alternatively you can use the .prevent modifier.
<button v-on:click.prevent="submit">Submit</button>

Related

how to add vue output inside input value=""

I have this code which output some values according to my users location and I want to display this values, On input but when I use <input value="{{useragent}}" /> it is just displaying {{useragent}} not the output.
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body translate="no">
<div id="app">
<p>{{useragent}}</p>
<p>{{tsFormatted}}</p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script id="rendered-js">
new Vue({
el: "#app",
data() {
return {
response: null,
ip: null,
useragent: null,
ts: null,
};
},
watch: {
// This should do a substring of the result returned by CloudFlare
response: function () {
this.ip = this.response.substring(this.response.search("ip=") + 3, this.response.search("ts="));
this.ts = this.response.substring(this.response.search("ts=") + 3, this.response.search("visit_scheme="));
this.useragent = this.response.substring(this.response.search("uag=") + 4, this.response.search("colo="));
},
},
computed: {
tsFormatted() {
return new Date(this.ts * 1000);
},
},
mounted() {
// Get the user's states from the cloudflare service
axios.get("https://www.cloudflare.com/cdn-cgi/trace").then((response) => (this.response = response.data));
},
});
//# sourceURL=pen.js
</script>
</body>
</html>
how can I display this {{values}} inside HTML <input> tag ?
When dealing with inputs, if you want useragent to fill the input field then use v-model instead of value
<input v-model="useragent" />
You can read more about it from Vue 2 DOCs: https://v2.vuejs.org/v2/guide/forms.html
You need to bind values :value or v-bind:value:
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body translate="no">
<div id="app">
<input :value="useragent" />
<input v-bind:value="tsFormatted" />
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script id="rendered-js">
new Vue({
el: "#app",
data() {
return {
response: null,
ip: null,
useragent: null,
ts: null,
};
},
watch: {
// This should do a substring of the result returned by CloudFlare
response: function () {
this.ip = this.response.substring(this.response.search("ip=") + 3, this.response.search("ts="));
this.ts = this.response.substring(this.response.search("ts=") + 3, this.response.search("visit_scheme="));
this.useragent = this.response.substring(this.response.search("uag=") + 4, this.response.search("colo="));
},
},
computed: {
tsFormatted() {
return new Date(this.ts * 1000);
},
},
mounted() {
// Get the user's states from the cloudflare service
axios.get("https://www.cloudflare.com/cdn-cgi/trace").then((response) => (this.response = response.data));
},
});
//# sourceURL=pen.js
</script>
</body>
</html>
<input type="text" :value="useragent" />
or
<input type="text" v-model="useragent" />
vue Form Input Bindings doc
Before went to the solution, I have a question to you - Do you want one-way or two-way data binding for your input ?
If you will use :value, It will work as a one-way data binding and will just update the input value but if you will make any changes in your input it will not modify the model/variable.
If you will use v-model, It will work as a two way data binding and will update both input as well as model/variable if any changes happen at any end.
Live Demo :
new Vue({
el:'#app',
data:{
name:'Alpha'
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.4/vue.js"></script>
<div id="app">
<div>One Way binding <input type="text" :value="name"/></div>
<div>Two way binding : <input type="text" v-model="name"/> </div>
<div>Result : {{name}}</div>
</div>

Why v-for won't render any DOMs? 'Property or method "data" is not defined on the instance but referenced during render.'

I would like to render several div containers depending on a returned API call from axios/vue. The axios call and callback work just fine, but vue won't render any divs.
Since I am using Django, I already changed the delimiters from curly brackets (which is Django default as well).
Error message in console:
Property or method "data" is not defined on the instance but referenced during render.
Make sure that this property is reactive, either in the data option,
or for class-based components, by initializing the property.
Please find a minimal code snippet as follows (if you remove the JS part the html will show up):
Thank you in advance for your help!
var app = new Vue({
delimiters: ['[[', ']]'],
el: '.EUR_Quotes',
data: {
info: []
},
created() {
axios
.get("http://data.fixer.io/api/latest?access_key=XXXd&base=EUR")
.then(response => {
this.info = response.data.rates;
console.log(response);
});
}
});
.EUR_Quotes {
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<html>
<head>
</head>
<body>
<div v-for="rates in info">
<div class="EUR_Quotes">[[ data ]]
</div>
</div>
</body>
<script src="https://unpkg.com/vue#2.5.13/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</html>
You are confusing your data variable name, it should be info in your template, (not data) the actual data object is the container for all your vuejs app's data.
Check the snippet, it works fine.
var app = new Vue({
delimiters: ['[[', ']]'],
el: '.EUR_Quotes',
data: {
info: []
},
created() {
axios
.get("http://data.fixer.io/api/latest?access_key=d&base=EUR")
.then(response => {
this.info = response.data.rates;
console.log(response);
});
}
});
.EUR_Quotes {
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<html>
<head>
</head>
<body>
<div v-for="rates in info">
<div class="EUR_Quotes">[[ info ]]
</div>
</div>
</body>
<script src="https://unpkg.com/vue#2.5.13/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</html>

Typeahead JS Autocomplete not working - can't find anything

I want to make a autocomplete function on my input with existing titles from database, but seems that doesn't work. I don't know what's the problem but when I try to write something, notting happens.
Here is my controller
public function search()
{
return view('search-me');
}
public function autocomplete(Request $request)
{
$data = Models::select("email")->where("email", "LIKE","%{$request->input("query")}%")->get();
return response()->json($data);
}
Here is my route
Route::get('search-me', array('as' => 'search', 'uses' => 'AdminNewsController#search'));
Route::get('autocomplete',array('as' => 'autocomplete', 'uses' => 'AdminNewsController#autocomplete'));
Here is my view
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.js"></script>
</head>
<body>
<div class="container">
<h1> test</h1>
<input type="text" class="typeahead form-control">
</div>
</body>
<script type="text/javascript">
var path = "{{ route('autocomplete') }}";
$('input.typeahead').typeahead({
source: function (query, process){
return $.get(path, { query: query}, function (data) {
return process(data);
});
}
});
</script>
</html>
I'm using Laravel 5.2 but I guess is working on mine too. Here is the tutorial : https://www.youtube.com/watch?v=3AiMsvobceY

How do I call a function from my JS file in my html?

I'm trying to call the function that I have written in the JS file, however, nothing is happening when I run the server. I'm not quite sure what I'm doing wrong and I could really use some guidance.
HTML:
<!DOCTYPE html>
<html>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="group.js"></script>
<body>
<div class="emailForm">
<input type="text" name="e">
<input type="submit" onclick="addEmail(e)" value="Submit">
</div>
</body>
</html>
JS:
...
function addEmail(e){
alert("test");
user = {
email: e,
role: "MEMBER"
};
var group = "test#googlegroups.com";
fetch('https://www.googleapis.com/admin/directory/v1/groups/'+ group +'/members',{ method: 'POST', body: $scope.user })
.then(res => res.json())
.then(json => console.log(json));
}
remove the parameter from the function in js code.
function addEmail(){
var e=document.getElementById('email');
alert("test");
user = {
email: e,
role: "MEMBER"
};
var group = "test#googlegroups.com";
fetch('https://www.googleapis.com/admin/directory/v1/groups/'+ group
+'/members',{ method: 'POST', body: $scope.user })
.then(res => res.json())
.then(json => console.log(json));
}
and in HTML also add ID to input tag and call js function without parameter.
<!DOCTYPE html>
<html>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="group.js"></script>
<body>
<div class="emailForm">
<input type="text" id="email" name="email">
<input type="submit" onclick="addEmail()" value="Submit">
</div>
It is good to separate html markup and javascript code by assigning event handlers either by native javascript methods or those exposed with libraries such as jQuery. In the original code the addEmail function was called from an inline event handler with a single argument e which is generally assigned as the event ~ in this case click
As the function itself took a single argument e and the function was called with the same, non-quoted, argument e it referred to the actual click event and not the HTML element with name e. By explicitly referring to the element from within the function by name this problem is alleviated and the code triggers the fetch request OK but cannot be further tested due to being rejected by Google - error follows.
<!DOCTYPE html>
<html>
<head>
<script src='//code.jquery.com/jquery-1.10.2.js'></script>
<script src='group.js'></script>
<script>
document.addEventListener('DOMContentLoaded',e=>{
const addEmail=function(){
let user = {
email: document.querySelector( 'input[name="e"]' ).value,
role: "MEMBER"
};
let group = "test#googlegroups.com";
/* what is $scope??? */
fetch( 'https://www.googleapis.com/admin/directory/v1/groups/'+ group +'/members',{ method: 'POST', body: $scope.user } )
.then( res => res.json() )
.then( json => console.log( json ) );
}
document.querySelector('input[type="submit"]').addEventListener('click',event=>{
addEmail.call( this );
})
});
</script>
</head>
<body>
<div class="emailForm">
<input type="text" name="e" />
<input type="submit" />
</div>
</body>
</html>
The rejection error
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}

VueJS api call leaving data undefined

I am learning VueJS 2.0 and I am connecting to an API where I want the value of some data to change on input change. Here is what the output says using the dev tools:
canadianDollar:undefined
europeanEuro:undefined
europeanPound:undefined
usd:"1232"
Whenever I put 1232 in the USD input field it doesn't return anything and leaves those properties as undefined. Here is the code.
new Vue({
el: '#app',
data: {
usd: '',
canadianDollar: '',
europeanPound: '',
europeanEuro: ''
},
// Watch methods
watch: {
usd: function() {
this.convertCurrency()
}
},
// Logic Methods
methods: {
convertCurrency: _.debounce(function() {
var app = this;
if (app.usd.length !== 0) {
// Show that the things are loading in.
app.canadianDollar = 'Searching...'
app.europeanPound = 'Searching...'
app.europeanEuro = 'Searching...'
console.log(app.usd)
axios.get("http://api.fixer.io/latest?base=USD&" + app.usd)
.then(function(response) {
app.canadianDollar = response.data.CAD
app.europeanPound = response.data.GBP
app.europeanEuro = response.data.EUR
})
.catch(function(error){
app.canadianDollar = "ERROR"
app.europeanPound = "ERROR"
app.europeanEuro = "ERROR"
})
}
}, 500)
}
})
and the HTML:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Vue</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" name="" value="" v-model="usd">
<ul>
<li>Canadian Dollar: {{canadianDollar}}</li>
<li>European Pound: {{europeanPound}}</li>
<li>European Euro: {{europeanEuro}}</li>
</ul>
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js" charset="utf-8"></script>
<script src="index.js" charset="utf-8"></script>
</body>
</html>
When I type in a number it does give me the "Searching" part but disappears and nothing shows up.
I would recommend changing
then(function(response) {
app.canadianDollar = response.data.CAD
app.europeanPound = response.data.GBP
app.europeanEuro = response.data.EUR
})
to
then(function(response) {
console.log(response);
})
that was you can see what is being returned.
Also, axios.get("http://api.fixer.io/latest?base=USD&" + app.usd) should probably have a name like vulue:axios.get("http://api.fixer.io/latest?base=USD&VALUE=" + app.usd), but you'll have to check their api to see what it is meant to be called.
...
response.data.rates.CAD;
you have
response.data.CAD;
...
app.canadianDollar = response.data.rates.CAD * app.usd;

Categories