can't set select defaut value - laravel

temlate
<bm-offer-confirm inline-template>
<select v-model="selectedCard">
<option v-for="card in cards"
v-bind:value="card.id">#{{card.info}}</option>
</select>
</bm-offer-confirm>
in the component
module.exports = {
data() {
return {
selectedCard: 0,
cards: {},
}
}
created(){
Bus.$on('setCardsList', function (cards) {
self.cards = cards;
this.selectedCard = cards[0].id;
//alert(this.selectedCard) shows 2
});
}
if i set selectedCard: 2 in data() it's work correctly and option is selected, but in my example it does not work. selected value is empty(not checked), why? I can select option only manualuty.
How you fill the cards object ? Are you getting any exception in console ?
No, it's result of emited in other component
created() {
this.getCards();
},
methods: {
getCards() {
this.$http.get('/get-cards/')
.then(response => {
this.cards = response.data;
Bus.$emit('setCardsList', this.cards);
})
},
//The Bus is Vue object;
//window.Bus = new Vue();

omg, I fixed it
created(){
var self = this; //add self link
Bus.$on('setCardsList', function (cards) {
self.cards = cards;
self.selectedCard = cards[0].id; // before this.selectedCard = cards[0].id;
//alert(this.selectedCard) shows 2
});
}

Related

Vue js how to chek multiple v-if condition from one function return in same page

This is my code
<button v-if="$can('permission-a')">Add User</button>
<button v-if="$can('permission-b')">Add Employee</button>
And this is my $can method
data() {
return {
returnAccess: false
};
},
methods: {
$can(permissionName) {
let route = window.routes.permission;
let returnAccess;
axios
.get(route + `/${permissionName}`)
.then(resounse => {
if (resounse.data == 101) {
this.returnAccess = true;
}
})
.catch(error => {
this.returnAccess = false;
});
return this.returnAccess;
},
}
$can method return false for add user button and return true for add employee button. But add user button also showing because of true return for add employee button.
How can i solve this issue. Any one can help me?
Thanks in advance.
First of all you don't need to return a value
create a permissions object:
data() {
return {
permissions: {}
};
and a method like:
methods: {
$can(permissionName) {
let route = window.routes.permission;
let returnAccess;
axios
.get(route + `/${permissionName}`)
.then(resounse => {
if (resounse.data == 101) {
this.permissions.permissionName = true;
}
})
.catch(error => {
this.permissions.permissionName = false;
});
},
}
now foreach this in your created()
created() {
let permissionNames = ['a', 'b'];
permissionNames.forEach(function(permissionName) {
this.$can(permissionName) {
});
}
this way you create a object with keys as the permisson.
now in html you can simple do:
<button v-if="permission.somePermission">Add User</button>
<button v-if="permission.somePermission">Add Employee</button>
NOTE: not tested, but hope you get the idea

vue.js Failed to mount component: template

i am working hard to solve this issue but not found any one please help me about this
here is my code
calling component
Vue.component('select2', require('./components/select2.vue'));
html of component
<template>
<select>
<slot></slot>
</select>
</template>
here is my vue.js script
<script>
export default {
props: ['options', 'value', 'params'],
mounted: function () {
var vm = this;
var params = !this.params ? {} : this.params;
params.val = this.value;
if(this.options) {
params.data = this.options;
}
$(this.$el).val(this.value);
$(this.$el).select2(params);
$(this.$el).on('change', function () {
vm.$emit('input', $(this).val())
})
$(this.$el).val(this.value).trigger('change');
},
watch: {
value: function (value) {
$(this.$el).val(value);
},
options: function (options) {
var params = !this.params ? {} : this.params;
if(this.options) {
params.data = this.options;
}
$(this.$el).select2(params);
}
},
destroyed: function () {
$(this.$el).off().select2('destroy')
}
}
</script>
but still getting this error i tried alot of things but not working please help me i can give you more detials if you needed i am using laravel ,gulp etc

Sort() not working

I'm having an issue with the sort() in ranking data from coinmarketcap api. With an ajax api call, sort works in returning an array with the right ranking. With an axios api call, seen below, it doesn't.
Here is my code using axios and vue.js:
let coinMarket = 'https://api.coinmarketcap.com/v2/ticker/?limit=10'
let updateInterval = 60 * 1000;
let newApp = new Vue({
el: '#coinApp',
data: {
// data within an array
results: []
},
methods: {
getCoins: function() {
axios
.get(coinMarket)
.then((resp) => {
this.results = formatCoins(resp);
});
},
getColor: (num) => {
return num > 0 ? "color:green;" : "color:red;";
},
},
created: function() {
this.getCoins();
}
})
setInterval(() => {
newApp.getCoins();
},
updateInterval
);
function formatCoins(res) {
var coinDataArray = []
Object.keys(res.data).forEach(function(key) {
coinDataArray.push(res.data[key])
})
coinDataArray.sort(function(a,b) {
return a.rank > b.rank
})
console.log(coinDataArray)
}
Where am I going wrong?
If you look into the data responded by https://api.coinmarketcap.com/v2/ticker/?limit=10, you will find the data you need is under res.data.data, not res.data.
So within the function=formatCoins, replace res.data with res.data.data, then works.
Vue.config.productionTip = false
let coinMarket = 'https://api.coinmarketcap.com/v2/ticker/?limit=10'
let updateInterval = 60 * 1000;
function formatCoins(res) {
var coinDataArray = []
Object.keys(res.data.data).forEach(function(key) {
coinDataArray.push(res.data.data[key])
})
coinDataArray.sort(function(a,b) {
return a.rank - b.rank
})
return coinDataArray
}
let newApp = new Vue({
el: '#coinApp',
data: {
// data within an array
results: []
},
methods: {
getCoins: function() {
axios
.get(coinMarket)
.then((resp) => {
this.results = formatCoins(resp);
});
},
getColor: (num) => {
return num > 0 ? "color:green;" : "color:red;";
},
},
created: function() {
this.getCoins();
}
})
setInterval(() => {
newApp.getCoins();
},
updateInterval
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
<script src="https://unpkg.com/vue#2.5.16/dist/vue.js"></script>
<div id="coinApp">
<div v-for="(record, index) in results" :key="index">
{{index}} - {{record.name}}: {{record.rank}}
</div>
</div>

Get component to wait for asynchronous data before rendering

I am calling an endpoint to bring back an object, which does fetch the data, however not fast enough for the component to grab the data and render. Instead, the component renders with blank values where there should be data.
If I break point the code on creation, then continue maybe a second later, the text correctly renders.
How do I implement it to not render until the data is back?
My API call:
checkScenarioType: function () {
this.$http.get('ScenariosVue/GetScenarioTypeFromParticipant/' + this.ParticipantId).then(response => {
// get body data
this.ScenarioType = response.body.value;
if (this.ScenarioType.timeConstraint) {
store.commit('switchConstraint');
}
}, response => {
// error callback
});
}
The component having the issues:
var questionArea = Vue.component('questionarea', {
props: ["scenariotype"],
data: function () {
return ({
position: "",
vehicleType: ""
});
},
methods: {
transformValuesForDisplay: function () {
switch (this.scenariotype.perspective) {
case 1: {
this.position = "Driver";
this.vehicleType = "Autonomous";
break;
}
case 2: {
this.position = "Passenger";
this.vehicleType = "Manually Driven";
break;
}
case 3: {
this.position = "Driver";
this.vehicleType = "Manually Driven";
break;
}
}
}
},
beforeMount() {
this.transformValuesForDisplay();
},
template:
`<h1>You are the {{ this.position }}! What should the {{ this.vehicleType }} car do?</h1>`
});
In cases like there's asynchronous loading of data, we typically use a simple v-if to hide the element until the data is present.
The template would be like:
<h1 v-if="position">You are the {{ position }}! What should the {{ vehicleType }} car do?</h1>
Notice the use of this in the template is unnecessary.
Also, in your case, instead of the beforeMount() hook, you would add a (deep/immediate) watch to the prop, to pick up changes when it is loaded externally:
watch: {
scenariotype: {
handler: function(newValue) {
this.transformValuesForDisplay();
},
deep: true,
immediate: true
}
},
Full demo below.
Vue.component('questionarea', {
props: ["scenariotype"],
data: function () {
return ({
position: "",
vehicleType: ""
});
},
methods: {
transformValuesForDisplay: function () {
switch (this.scenariotype.perspective) {
case 1: {
this.position = "Driver";
this.vehicleType = "Autonomous";
break;
}
case 2: {
this.position = "Passenger";
this.vehicleType = "Manually Driven";
break;
}
case 3: {
this.position = "Driver";
this.vehicleType = "Manually Driven";
break;
}
}
}
},
watch: {
scenariotype: {
handler: function(newValue) {
this.transformValuesForDisplay();
},
deep: true,
immediate: true
}
},
template:
`<h1 v-if="position">You are the {{ position }}! What should the {{ vehicleType }} car do?</h1>`
});
new Vue({
el: '#app',
data: {
ScenarioType: {perspective: null}
},
methods: {
checkScenarioType: function () {
this.$http.get('https://reqres.in/api/users/2').then(response => {
// get body data
this.ScenarioType.perspective = response.body.data.id; // for testing purposes only
}, response => {
// error callback
});
}
},
mounted: function() {
this.checkScenarioType();
}
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-resource"></script>
<div id="app">
<p>Notice while it is null, the h1 is hidden: {{ ScenarioType }}</p>
<br>
<questionarea :scenariotype="ScenarioType"></questionarea>
</div>

Marionette - throws error on `removeRegions` how to solve it

In my app, i have the regions as header,content,footer - in which on the login page, I don't want to use the header, and footer. for that, on onRender i remove the regions what i don't want to be.
But I am getting an error saying: Cannot read property 'empty' of undefined.
here is my template : (i use jade )
div#wrapper
script(type='text/template', id="appTemplate")
div#header
div#content
div#footer
script(type='text/template', id="loginTemplate")
div this is login template
here is my layout.js:
socialApp.AppLayout = Backbone.Marionette.LayoutView.extend({
el:'#wrapper',
template:'#appTemplate',
regions: {
header : '#header',
content : '#content',
footer : '#footer'
},
onRender : function () {
this.removeRegion("header", "#header"); //i am removing header alone here.
}
});
here is my controller.js
socialApp.loginController = Marionette.Controller.extend({
_initialize:function(){
this.loginView = new loginView({model:new loginModel});
this.layout.onRender(); //calling onRender from here...
this.layout.content.show(this.loginView);
}
});
But it's all not working. any one help me the correct way please?
You should never call methods that are prefixed with on manually. Those are there for your code to react to given events, in this case that the view’s render method was invoked.
I would suggest that you instead of trying to remove and then later re-add regions, you create two different layouts. Then when your router hits the login route, you render LoginLayout into your App’s root region, and for other routes, the ‘normal’ layout. Here’s how I solved something similar:
app.js:
var App = new Marionette.Application;
App.addRegions({ root: '#acme' });
// Instantiate User model
App.addInitializer(function()
{
this.user = new UserModel;
});
// Render App layout
App.addInitializer(function()
{
this.layout = this.user.get('id') ? new ContentLayoutView({ identifier: 'content' }) : new UserLayoutView({ identifier: 'user' });
this.root.show(this.layout);
// And let the routers decide what goes in the content region of each layout
this.router = {
content: new ContentRouter,
user: new UserRouter
};
});
layout/content.js
var ContentLayout = Marionette.LayoutView.extend(
{
identifier: 'content',
template: ContentLayoutTemplate,
regions: {
content: '[data-region="content"]',
panelLeft: '[data-region="panel-left"]',
panelRight: '[data-region="panel-right"]'
},
initialize: function()
{
this.content.once('show', function(view)
{
this.panelLeft.show(new PanelLeftView);
this.panelRight.show(new PanelRightView);
}.bind(this));
}
});
layout/user.js
var UserLayout = Marionette.LayoutView.extend(
{
identifier: 'user',
template: UserLayoutTemplate,
regions: {
content: '[data-region="content"]'
}
});
router/content.js
var ContentRouter = Marionette.AppRouter.extend(
{
routes: {
'(/)': '...'
},
createLayout: function(callback)
{
if(App.root.currentView.options.identifier != 'content')
{
var layout = new ContentLayoutView({ identifier: 'content' });
this.region = layout.content;
this.listenTo(layout, 'show', callback);
App.root.show(layout);
}
else
{
this.region = App.root.currentView.content;
callback();
}
},
execute: function(callback, args)
{
if(App.user.get('id'))
{
this.createLayout(function()
{
callback.apply(this, args);
}.bind(this));
}
else
App.router.user.navigate('login', true);
}
});
router/user.js
var UserRouter = Marionette.AppRouter.extend(
{
routes: {
'login(/)': 'showLogin',
'logout(/)': 'showLogout'
},
createLayout: function(callback)
{
if(App.root.currentView.options.identifier != 'user')
{
var layout = new UserLayoutView({ identifier: 'user' });
this.region = layout.content;
this.listenTo(layout, 'show', callback);
App.root.show(layout);
}
else
{
this.region = App.root.currentView.content;
callback();
}
},
execute: function(callback, args)
{
this.createLayout(function()
{
callback.apply(this, args);
}.bind(this));
},
showLogin: function()
{
var LoginView = require('view/detail/login');
this.region.show(new LoginView);
},
showLogout: function()
{
var LogoutView = require('view/detail/logout');
this.region.show(new LogoutView);
}
});

Resources