Use moustache inside moustache brackets in vue? - javascript

I’m pretty new to Vue.js and love it so far. There’s only one problem I have: How do I render a string AND things inside the string?
For example:
//…
data:{
string:"hi, {{name}}",
name:"John Doe"
}
{{string}}<!—won’t work —>
<span v-html="string"></span><!—neither this —>
I want to insert “string” into the html and afterwords insert “name”.
The “Hello {{name}}” should inserted after an Ajax call and therefore not be featured in the HTML.
The output should be “hi, John Doe”.
To make it clear, what I want to have is:
{{string}}
<!-- becomes-->
hi, {{name}}
<!--finally becomes-->
hi, John Doe

Use a computed property to return string with data variable inside string;
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="app">
<h1>{{this.stringWithVar}}</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
name: 'John Doe'
},
computed: {
stringWithVar: function () {
return `hi, ${this.name}`;
}
}
})
</script>
</body>
</html>

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>

How to access Spring Boot model with Vue?

I am not sure how to access a model I create with my controller with Vue in my html. I know how to access model attributes with thymeleaf, but cannot find any info anywhere on how to access them with Vue. I would like to store the count value from the controller in the Vue data count I have below. I am using Vue within my template hosted with CDN, not as a separate project.
Here is my controller:
#PostMapping("/word")
public String searchSentence(#ModelAttribute WordSearch wordSearch, Model model) {
int c = wordSearch.search();
String count = String.valueOf(c);
model.addAttribute("wordSearch", wordSearch);
model.addAttribute("count", count);
return "count";
}
Here is the count.html:
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Count-Form</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<h1>Result</h1>
<p th:text="'sentence: ' + ${wordSearch.sentence}" />
<p th:text="'word: ' + ${wordSearch.word}" />
<!--<p th:text="'count: ' + ${count}" /> -->
<div id="count-text" style="display: none">
<p th:text="${count}" />
</div>
<div id="app">
{{count}}
</div>
<script>
new Vue({
el: '#app',
data() {
return {
count: ""
}
},
created() {
this.count = ???
}
})
</script>
Submit another message
</body>
</html>
You can follow this blog to do what you desire. https://dev.to/brunodrugowick/spring-boot-vue-js-axios-and-thymeleaf-with-bootstrap-in-4-commits-2b0l. In this author explains how you can use Thymeleaf and VueJS together by adding VueJS dependency in pom.xml.
you need following dependency in your pom xml to use VueJS,
<dependency>
<groupId>org.webjars</groupId>
<artifactId>vue</artifactId>
<version>2.6.11</version>
</dependency>
Thymeleaf is a server-side Java template engine, while Vue is a JS framework to build frontend layer. The best way to connect Spring with Vue would be by an API.
So you'll need to expose your data as a JSON, make a http call vue app -> java api and consume the response.
Here you can find more details, how this works
All you have to do is create a method returning ResponseBody, then you call this method in Vue (Axios is a good option!).
Example 1: function to get a String variable:
#GetMapping( "/getLanguage")
#ResponseBody
public String obtenerIdiomaActual() {
return languageService.getLanguage();
}
Then you'd need a method in your Vue app to read this value:
const vm = Vue.createApp({
data() {
return {
language: null,
}
},
methods: {
getLanguage() {
axios.get(window.location.origin + '/getLanguage')
.then(response => {
this.language = response.data;
})
.catch(error => {
this.errorMessage = error.message;
console.error("There was an error!", error);
});
},
mounted: function () {
this.getLanguage();
},
watch: {
idioma: function () {
console.log("Language: " + this.language);
}
},
}).mount('#myApp')
You can use all kind of complex data: objects, arrays, dictionaries (maps)...
#GetMapping( "/getComplexData")
#ResponseBody
public Map<String, List<SpaceBean>> getMyComplexData() ...
And read the response easily with Vue:
<div v-for="(spaceList, key) in datos">
<p v-cloak><b>{{key}}</b></p>
<table class="display" style="width: 100%" v-cloak>
<tbody>
<tr v-for="space in spaceList">
<td>{{space.alias}}</td>
<td>{{space.descripcion}}</td>
<td>{{space.url}}</td>
</tr>
...
I hope this help a little!!

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>

How to temporize the analysis of an <input> field?

I would like to analyze the content of an <input> field when there is no user activity.
I will take below a simple example (counting the number of characters) but the actual analysis if very expensive so I would like to do it in batches, when there is some inactivity of the user instead of doing it at every change of the bound variable.
The code for the straightforward analysis could be
var app = new Vue({
el: '#root',
data: {
message: ''
},
computed: {
// a computed getter
len: function() {
// `this` points to the vm instance
return this.message.length
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script>
<div id="root">
<input v-model="message">Length: <span>{{len}}</span>
</div>
My problem is that function() is called at each change of message. Is there a built-in mechanism to throttle the query, or a typical approach to such a problem in JS?
That works the way it is supposed to. As it is said in the docs:
It will update any bindings that depend on computed property when the original data changes
But there's a way to do it:
var app = new Vue({
el: '#root',
data: {
message: '',
messageLength: 0
},
methods: {
len: _.debounce(
function() {
this.messageLength = this.message.length
},
300 // time
)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script>
<script src="https://unpkg.com/underscore#1.8.3"></script> <!-- undescore import -->
<div id="root">
<input v-model="message" v-on:keyup="len">Length: <span>{{ messageLength }}</span>
</div>
Full example: https://v2.vuejs.org/v2/guide/computed.html#Watchers
p.s. A comment about computed being sync from the vue's author: https://forum-archive.vuejs.org/topic/118/throttle-computed-properties/3
p.p.s Classics article about difference between debounce and throttle.

Selection in first drop down populates data in second dropdown but only on first click, why?

I have 2 drop downs where selection of first drop down effects the data content of the second drop down.
The problem I have is this functionality is occurring only on first click instead it should happen every time.
Here is my jsFiddle with my working code and here is my code on jsbin(jsbin gives some error which I am unable to understand, help appreciated here too, #newbieTorture).
Thanks in Advance :)
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.ArticleAdapter= DS.FixtureAdapter.extend({});
App.Article =DS.Model.extend({
title: DS.attr(),
body: DS.attr(),
shouldReloadAll:true,
comments: DS.hasMany('comment', {async : true})
//async tells compiler to load data from comment everytime this is rendered
});
App.Comment =DS.Model.extend({
text: DS.attr(),
shouldReloadAll:true,
article: DS.belongsTo('article', { async: true })
});
App.Article.FIXTURES=[
{
id:1,
title : 'Ember',
body:'Its a great technology but need lot of studying and practice',
comments:[1]
},{
id:2,
title : 'Angular',
body:'it takes less understanding but has more coding the ember',
comments:[2,3]
//this will be an aray coz it is has many relation
}
];
App.Comment.FIXTURES=[
{
id:1,
text : 'Yyyieee excited to learn ember',
aricle: 1
//its not an array coz it will be related to single object
},{
id:2,
text : 'I will start Angular once i have fininshed with ember',
article: 2
},{
id:3,
text : 'Angular can be interesting',
article: 2
}
];
App.CommentAdapter= DS.FixtureAdapter.extend();
App.IndexController = Ember.ArrayController.extend({
articleValue: null,
selected: null,
articleStore: Em.computed(function(){
console.log("data is : " + this.get('articleValue'));
console.log("data is : " + this.get('selected'));
return this.store.findAll("article");
}).property("selected"),
availableComment: Em.computed(function () {
var make = this.get('selected');
// the line below returns the id and not an object
console.log(make);
if (make === undefined || make === null)
return [];
return this.get('selected').get('comments');
}).property('articleValue'),
actions:{
callIndexController: function(){
var select= this.get("selected");
console.log("hi :" + select);
}
}
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return [];
},
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" id="index">
First drop down:
{{
view "select"
contentBinding=articleStore
optionLabelPath="content.title"
optionValuePath="content.id"
prompt="Pick a person:"
shouldReloadAll=true
selectionBinding=selected
valueBinding=articleValue
}}
<br>
<br>
Second drop down:
{{
view "select"
contentBinding=availableComment
optionLabelPath="content.text"
optionValuePath="content.id"
prompt="related task:"
shouldReloadAll=true
valueBinding=articleValue
}}
</script>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember-template-compiler.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember.debug.js"></script>
<script src="http://builds.emberjs.com/tags/v1.13.7/ember-data.js"></script>
<script src="js/amit_dropdown.js"></script>
<!-- to activate the test runner, add the "?test" query string parameter -->
<script src="tests/runner.js"></script>
</body>
</html>

Categories