# [Vue.js] VueJS conditionally add an attribute for an element Subscribe to RSS

In VueJS we can add or remove a DOM element using v-if:

<button v-if=”isRequired”>Important Button</button>

but is there a way to add / remove attributes of a dom element eg for the following conditionally set the required attribute:

by something similar to:

Any ideas?

### Solution :

Try:

<input :required=”test ? true : false”>

### Solution 2:

Simplest form:

<input :required=”test”> // if true
<input :required=”!test”> // if false
<input :required=”!!test”> // test ? true : false

### Solution 3:

<input :required=”condition”>

You don’t need <input :required=”test ? true : false”> because if test is truthy you’ll already get the required attribute, and if test is falsy you won’t get the attribute. The true : false part is redundant, much like this…

if (condition) {
return true;
} else {
return false;
}
// or this…
return condition ? true : false;
// can *always* be replaced by…
return (condition); // parentheses generally not needed

The simplest way of doing this binding, then, is <input :required=”condition”>

Only if the test (or condition) can be misinterpreted would you need to do something else; in that case Syed’s use of !! does the trick.
<input :required=”!!condition”>

### Solution 4:

there is been through the same problem, and tried above solutions !!
Yes, I don’t see the prop but that actually does not fulfils what required here.

My problem -

let isValid = false
<any-component
:my-prop=”isValue ? ‘Hey when when the value exist’: false”
/>

In the above case, what I expected is not having my-prop get passed to the child component - <any-conponent/> I don’t see the prop in DOM but In my <any-component/> component, an error pops out of prop type check failure. As in the child component, when expecting my-prop to be a String but it is boolean.

myProp : {
type: String,
required: false,
default: ‘’
}

Which means that child component did receive the prop even if it is false. Tweak here is to let the child component to take the default-value and also skip the check. Passed undefined works though!

<any-component
:my-prop=”isValue ? ‘Hey when when the value exist’ : undefined”
/>

This works and my child prop is having the default value.

# [Vue.js] VueJs templating. How to load external templates Subscribe to RSS

I’m new to Vue.js, I’ve used AngularJS for some time and in angular we used to load templates such as,

template: ‘/sometemplate.html’,
controller: ‘someCtrl’

How can we do such a thing in Vue, instead of keeping large HTML templates inside JavaScript like this,

new Vue({
el: ‘#replace’,
template: ‘<p>replaced</p>’
})

This is OK for small templates but for large templates is this practical?

Is there a way to load external template HTML or use HTML template inside a script tag like in Vue?

<script type=”x-template” id=”template>HTML template goes here</html>

### Solution :

You can use the script tag template by just referring to its id.

{
template: ‘#some-id’
}

Though, I highly recommend using vueify (if you use browserify) or vue-loader (if you use webpack) so you can have the components stored in nice little .vue.js files like this.

Also, the author of vue.js wrote a nice post about the topic of external template urls:

https://vuejs.org/2015/10/28/why-no-template-url/

### Solution 2:

You can try this:

Example:

new Vue({
components: {
},

### Solution 3:

David, that is a nice example, but what’s the best way to make sure the DOM is compiled?

https://jsfiddle.net/q7xcbuxd/35/

When I simulate an async operation, like in the example above, it works. But as soon as I load an external page “on the fly”, vue.js complains because the DOM is not ready.
More specifically:
Uncaught TypeError: Cannot set property ‘vue’ of undefined
Is there a better way to do this than to call $compile when the page has loaded? I’ve tried with$mount, but that didn’t help.

UPDATE:
Never mind, I finally figured out how to do it:

Vue.component(‘async-component’, function (resolve, reject) {

### Solution 6:

Use browserify to bundle everything like this:

//Home.js

import vue.js from ‘vue’;

var Home = Vue.extend({
template: require(‘./Home.vue’)
});

export default Home;

//Home.vue
<h1>Hello</h1>

// And for the browserify bundle use a transform called stringify

… .transform(stringify([‘.html’, ‘.svg’, ‘.vue’, ‘.template’, ‘.tmpl’]));

### Solution 7:

I’ve tried http-vue-loader and it works fine.
This library is easy to use and has good documentation and examples

Although you can’t load templates from filed directly you still can keep html in separate single-file components. You can even skip <script>…</script> part.

my-component.vue

<template>
<div class=”hello”>Hello {who}</div>
</template>

index.html

<!doctype html>
<html lang=”en”>
<script src=”https://unpkg.com/vue"></script>

<body>
<div id=”my-app”>
<my-component></my-component>
</div>

<script type=”text/javascript”>
new Vue({
el: ‘#my-app’,
components: {
}
});
</script>
</body>
</html>

Both files should be placed in one folder at the same level

# [Vue.js] How to make a typing effect in vuejs Subscribe to RSS

hello j try to make a Typing effect on vuejs here is my code.

i’m trying to call setTimeout but it’s the effect i want.

template:

<template>
<div>
<div class=”img-container” >
<div class=”conversation”>
<span class=”name”>{getCharacter.name}</span>
<p class=”text typewriter-text”> {outputText}</p>
</div>
<button>Start</button>
</div>
<Counter ></Counter>
</div>

SCRIPT :
export default {
name: “Practice”,
methods: {
outText() {

if (this.inc < this.text1.length) {
this.outputText += this.text1.charAt(this.inc);
this.inc ++;
setTimeout(this.outText() , 100000)

}
}
},
mounted() {
this.outText()
},
data() {
return {
text1 :’’,
outputText : ‘’,
inc:0
}
}
}

css :

<style scoped>
.text {
background-color: #ababab;
margin: 0;
width: 85vw;
height: 10vh;
}

### Solution :

You should not be calling the outText method when you pass it as an argument to setTimeout, doing so will call the method immediately, instead you want to pass the method to setTimeout so it can be called later after the timeout has elapsed.

Incorrect:

setTimeout(this.outText(), 100000)

Correct:

setTimeout(this.outText, 100000)

Also 100000ms (100s) is too long of a delay to notice anything.

# [Vue.js] How can I transpose these rows into columns in Vue? Subscribe to RSS

when trying to reproduce this table in a way where users can select a number of personality traits:

there is done this, apart from my columns have turned into rows!

So you see that on the 1st row of the second image, they should all appear under the heading Sincerity, as per the first image - but they do not. How can I amend this table to look like the first image?

<table>
<tr>
</tr>
<tr v-for=”(column, index) in childs” :key=”index”>
<td v-for=”item in column” :key=”item.id”>
<Child
:selected=”selected.indexOf(item.text) > -1”
:text=”item.text”
@select=”selectItem”
/>
</td>
</tr>
</table>

Structure of my data:

childs: {
Sincerity: [
{
id: 1,
text: “Down-to-earth”
},
{
id: 2,
text: “Honest”
},
{ … }
],
Excitement: [
{
id: 12,
text: “Daring”
},
{
id: 13,
text: “Sprited”
},
{ … }
],
Competence: [
{
id: 23,
text: “Reliable”
},
{
id: 24,
text: “Intelligent”
},
{ … }
]

### Solution :

I’d suggest using display: flex to achieve this instead of a regular table.

With a table, in each cell (td) you’d need to figure out it’s header (th) above so you know from what list to get the trait.

With flex, you can group the columns properly, and the html can be as simple as

<div id=”app”>
<ul>
<span>{ child.text }</span>
</li>
</ul>
</div>
</div>

And the only css to get these into columns would be

#app {
display: flex;
}

there is a more complete jsfiddle here with how I would initially approach it

# [Vue.js] How to show refreshed value from an array Subscribe to RSS

My problem is in showing the values of the object.
The table shows the tasks and the remaining time to finish. But it does not update the countdown timer …
The values are in an Object in Task ID, for example:
Object {1: “4017 D 13 H 2 M 49 S”, 2: “0 D 0 H 0 M 0 S”, …}
This object should always be updated to show the remaining time, but in the table where I show the object the same is only with the first value, without updating the timer.

<template>

<table class=”table” style=”text-align: center”>
<tr>
<th scope=”col”>…</th>
<th scope=”col”>…</th>
<th scope=”col”>…</th>
<th scope=”col”>…</th>
<th scope=”col”>Time Left</th>
</tr>
<tbody>
</tbody>
</table>

</template>

<script>
export default {
// variables declaration
data() {
return {
user: [],
currentTime: [],
showLeft: {}
};
},

created() {
// ProgressBar animation starts
this.$Progress.start(); // Get data from server axios.get(“/user/name/data”).then(response => { this.user = response.data; axios.get(/user/missingTaskNum/data).then(response => { this.numTasks = response.data; axios.get(/user/missingTask/data).then(response => { this.tasks = response.data; // Call function that will calculate time left this.updateCurrentTime(); // ProgressBar animation stops this.$Progress.finish();
});
});
});
},

mounted() {
// start timer to refresh function every 1 sec
this.interval = setInterval(() => {

this.updateCurrentTime();

}, 1000);
},

methods: {

updateCurrentTime: function() {

var now = new Date().getTime();

for (let i = 0; i < this.tasks.length; i++) {

this.$Progress.start(); this.$Progress.finish();

} else {

var days = Math.floor(
this.currentTime[this.tasks[i].id] / (1000 * 60 * 60 * 24)
);

var hours = Math.floor(
(this.currentTime[this.tasks[i].id] % (1000 * 60 * 60 * 24)) /
(1000 * 60 * 60)
);

var minutes = Math.floor(
(this.currentTime[this.tasks[i].id] % (1000 * 60 * 60)) /
(1000 * 60)
);

var seconds = Math.floor(
(this.currentTime[this.tasks[i].id] % (1000 * 60)) / 1000
);

days + “ D “ + hours + “ H “ + minutes + “ M “ + seconds + “ S “;
}
}
console.log(this.showLeft);
}
},

beforeDestroy() {
clearInterval(this.interval);
}
};

</script>

### Solution :

You’re running into one of the change detection caveats, outlined here:

https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

Specifically on this line:

days + “ D “ + hours + “ H “ + minutes + “ M “ + seconds + “ S “;

The object this.showLeft is empty when it is created within data, so it won’t have any reactive properties. It works fine if you change it to this:

this.$set( this.showLeft, this.tasks[i].id, days + “ D “ + hours + “ H “ + minutes + “ M “ + seconds + “ S “ ) This tells vue.js to add a reactive property to showLeft, such that the UI will update when it changes. An alternative would be to create a new object each time: // Somewhere near the top of updateCurrentTime const showLeft = {}; // … set values on showLeft instead of this.showLeft this.showLeft = showLeft Personally I think I would make greater use of computed properties for this, rather than trying to do everything inside updateCurrentTime. I can’t be more specific given the code is incomplete. # [Vue.js] Where to store Laravel Passport client_secret in VueJS Subscribe to RSS when a bit new to VueJS and when using Laravel as API only and VueJS as a separate project. In my App.vue, there is following setup: http://api.com is my virtual host! <script> import axios from ‘axios’; export default { data () { return { } }, created() { const postData = { grant_type: “password”, client_id: 2, client_secret: ‘MvEyvm3MMr0VJ5BlrJyzoKzsjmrVpAXp9FxJHsau’, username: 'mail@gmail.com‘, password: ‘**********‘, scope: ‘’ } axios.post(‘http://api.com/oauth/token', postData) .then(response => { const header = { ‘Accept’: ‘application/json’, ‘Authorization’: ‘Bearer ‘ + response.data.access_token, }; axios.get(‘http://api.com/api/user', { headers: header }) .then(response => { console.log(response.data) }) }) } } </script> But this file is totally visible to front-end which is not good due to security reasons. What I did, I made a new route in Laravel as Route::post(‘get_client_creds’, MyController@index); and then made a request from axios as: axios.post(‘http://api.com/get\_client\_creds') .then(response => { this.client_secret = response.client_secret; }); And but then I thought anyone can also access the route using Postman or may be through console using axois, so can someone give me some suggestions about where to store these secrets??? Thanks in Advance! ### Solution : There are two different ways to specify config settings for vue #1 Vue.js non-cli projects, you can use src/config.js Create a new file src/config.js and add as following export const API_CLIENT_ID = ‘123654’; To use this, try import like: import { API_CLIENT_ID } from ‘../config’ // in the code console.log(API_CLIENT_ID); #2 For vue.js CLi projects follow these steps. You must use the .env files hold the configuration variables. It could be structured like .env # loaded in all cases .env.local # loaded in all cases, ignored by git .env.[mode] # only loaded in specified mode .env.[mode].local # only loaded in specified mode, ignored by git Here is how you can specify the variable. FOO=bar API_CLIENT_ID=123456 And you can use this as: console.log(process.env.API_CLIENT_ID) Please follow the documentation for more details. https://cli.vuejs.org/guide/mode-and-env.html#environment-variables # [Vue.js] The problem with rendering the text in Vue instance? Subscribe to RSS there is a vue.js instance called appDetails. This instance belongs to app.html. In it I declared function getApp, which returns the name of app: var appDetails = new Vue({ el: ‘#appDetails’, methods: { getApp() { var path = url; var formData = “id=” + id; return axios.get(path, formData) .then((res) => { return res.data.name; }) }) Then in another js file I created product instance. This js file belongs to product.html. In it I declared computed property. In body of property to call a function of appDetails vue.js instance. The returned data of the property is the name of app. var product = new Vue({ el: ‘#product’, computed : { app_name: function() { appDetails.getApp() .then((returnVal) => { return returnVal; }) }); In product.html I wrote: <a>{app_name}</a> But when I load page, there is no text. tag is empty. But when I tried to console log it showed me a name. Anybody knows how to solve this problem? ### Solution : app_name resolves to undefined because the function does not return anything. Computed properties cannot be asynchronous, so instead you should create a data field on the component and call an asynchronous function that populates it. If you only need to fetch the data once, then mounted is probably a good place to do this. var product = new Vue({ el: ‘#product’, data: function () { return { app_name: ‘’ } }, mounted: function () { appDetails.getApp() .then((returnVal) => { this.app_name = returnVal; }) } }); Also, does getApp() depend at all on the state of the AppDetails component? If not, it may make sense to keep it as a standalone function as it would be easier to use import it into both components. # [Vue.js] Why do I get an error for mutating Vuex store state outside of mutation handlers while inside a mutation handler? Subscribe to RSS when getting this error when I edit one of the text fields (which updates the store): I’ve already tried putting @change and v-model on the text fields and that is not proper. Need to find a proper way to mutate the state on an event triggered by the text field(s). Example: Profile.vue: <v-text-field @change=”setProfile(profileData)” v-model=”profileData.groupName” label=”Group Name”></v-text-field> Here is my code: Profile.vue: <v-text-field @change=”set” v-model=”profileData.groupName” label=”Group Name”></v-text-field> Profile.vue.js Javascript: import { mapGetters, mapMutations } from “vuex”; export default { name: “Profile”, created() { delete this.profileData; this.profileData = JSON.parse(JSON.stringify(this.getProfile())); console.log(this.profileData); }, data() { return { profileData: { groupName: null, groupClid: null, groupContact: null } }; }, methods: { set() { this.$store.commit(“setProfile”, this.profileData);
},
…mapGetters([“getProfile”]),
…mapMutations([“setProfile”])
}
}

build.js –> store.js:

const state = {
profile: {
“groupName”: “Happy group”,
“groupNumber”: “9999999999”,
“groupContact”: “Bob Ross”
}
};

const getters = {
getProfile: (state) => state.profile,
};

const actions = { };

const mutations = {
setProfile: (state, profile) => (state.profile = profile)
};

export default {
state,
getters,
actions,
mutations,
}

### Solution :

Remove delete this.profileData from created()
Change the set() to setData’
Change to Object.assign (shouldn’t matter if you use string->parse or Object.assign)
Put one change event on the card, above the text fields. This way, we don’t have to duplicate the vue-style event listener.

<template >
<v-container fluid>
<v-layout row wrap fill-height>
<v-flex xs6>
<v-card elevation=”10”>
<v-card-title primary-title class=”pb-0”>
<div>
</div>
</v-card-title>
<v-card-text @change=”setData”>
<v-container fluid>
<v-layout align-center row wrap>
<v-flex xs3>
<v-responsive>Group Name:</v-responsive>
</v-flex>
<v-flex xs9>
<v-text-field v-model=”profileData.groupName” label=”Group Name”></v-text-field>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
</v-card>
</v-flex>
</v-layout>
<v-spacer></v-spacer>
</v-container>
</template>

<script>
import { mapGetters, mapMutations } from “vuex”;

export default {
name: “Profile”,
created() {
this.profileData = Object.assign({}, this.getProfile());
},
data() {
return {
profileData: {}
};
},
methods: {
setData() {
this.setProfile(this.getData());
},
getData() {
return Object.assign({}, this.profileData);
},
…mapGetters([“getProfile”]),
…mapMutations([“setProfile”])
}
};
</script>

# [Vue.js] How to use an image as a button in Vue.js? Subscribe to RSS

I’m trying to make a login button as a single-file-component in Vue.js (it’s a Rails app with a Vue.js front-end). If you click this button, it’s supposed to take you to the an external provider’s login page.

How can I use an image as a button? I’m guessing you use v-on:click for the actual redirect, but I’m stuck there.

Right now, this code below shows a hardcoded button that looks like img(src=”../assets/img/login_button.png”). You can click on it, but that’s obviously not what I want. to show the actual png image, not the path.

<template lang=”pug”>

</template>

<script lang=”ts”>
import { Vue, Component } from ‘vue-property-decorator’;

@Component
export default class LoginButton extends Vue{
redirect_to_login():void{ // I haven’t written this method yet
}
}
</script>

### Solution :

Is there any reason you can’t just use normal HTML image inside the button? I haven’t used pug before.

Though since you’re using vue.js and not an actual HTML form you might not even need a button you could just add the click binding to the image instead

### Solution 2:

Either you can use:

<a @click=”Redirect”>
<img src=’IMAGE_SRC’ />
</a>

or

<img @click=”Redirect” src=’IMAGE_SRC’/>

new Vue({
el: ‘#app’,
methods:
{
Redirect()
{
window.location.href = “https://jsfiddle.net/";

//or

//this.$router.push(‘LINK_HERE’); // if ur using router } } }) Demo LINK: https://jsfiddle.net/snxohqa3/5/ # [Vue.js] Upload file using vue.js and spring-boot with axios Subscribe to RSS If have a form with a text field and file upload option. The file is called start.vue(say). From that a module.js(say) file is called. Using that service.js(say) is called. That service.js calls the api in moveController.java(say). when getting error as: Current request is not a multipart request Tried to find the syntax so that multipart header is retained till api is called. module.js is getting the appropriate file value. But no idea about service.js start.vue.js is: <script src=”https://unpkg.com/axios/dist/axios.min.js"></script> <script> export default { name: “BatchMove”, computed: { loading() { return this.$store.state.loader.loading;
},
msgs() {
return this.$store.state.moveBatchHistory.msg; } }, components: {}, data() { return { file: ‘’, emailId: ‘’ }; }, methods: { submitFile() { console.log(“logging email… “ + this.emailId); const { emailId, file } = this; this.$store.dispatch(“moveBatchHistory/ans”, { file, emailId });
},
this.file = this.$refs.file.files[0]; } } } </script> module.js is: import { moveBatchHistoryService } from ‘../_services’; export const moveBatchHistory = { namespaced: true, state: { msg: null }, actions: { ans({commit}, {file, emailId}) { moveBatchHistoryService.getSomething(file, emailId).then( response => { commit(“ans”, response); } ); } }, mutations: { ans(state, response) { state.msg = response } } } service.js is: import config from ‘../config’; import {authHeader} from ‘../_helpers’; import axios from ‘axios’; import {store} from ‘../_store’; export const moveBatchHistoryService = { getSomething }; function getSomething(file, emailId) { var headers = authHeader(); const requestOptions = { method: ‘POST’, headers: headers, params: { “file”: file, “Email”: emailId } }; return axios(${config.apiUrl}/api/moveBatch`, requestOptions)
.then(response => {
return response.data;
}).catch(() => {
store.dispatch(“alert/errorTime”, “Unable to process the request this time. Please try again latter.”);
});
}
‘’’

moveController.java is:

@RequestMapping(value = “/moveBatch”, method = RequestMethod.POST)
public void singleFileUpload(@RequestParam(“file”) MultipartFile file, String Email) throws Exception {}

current request is not multipart request in moveController.java

### Solution :

when not very good at vue.js but for posting the data you could refer this post

As for as backed is concern you have not mentioned whether the email is @RequestParam, @RequestBody. Use this below for that

@RequestMapping(value = “/moveBatch”, method = RequestMethod.POST)