vue v-show will not fire on data property change - methods

I have the following vue template
<button :disabled=isDisabled v-show="!isLast " type="button" id="next" class="survey-card__actions-right" v-on:click="next()">Next {{isLast}}</button>
<button v-show="isLast " class="survey-card__actions-right" type="button" v-on:click="sendSurvey()">Send</button>
and I have my
data() {
return {
isLast: false
}
}
and I have a next method which check the following
if(next[0].length == (cI + 2)) {
alert() //will alert
this.isLast = true
console.log(this.isLast) //true
}
but in template will never happen the change

Related

How do I display instant messages, when insecure is removed, with Meteor.methods and Meteor.call?

I am taking coding courses online, so I can build my app sometime next year...
Can you help me with this instant message code please?
a. I am supposed to display an alert message when the user is not logged in.
b. Display the usename in the header.
c. Display the username with his instant message.
Since insecure is removed, I have to use Meteor.methods and meteor.call. I cannot use Sessions. I keep getting weird errors...
Here is the javascript code I have tried based on the course module, but I get errors that don't make sense to me...
Messages = new Mongo.Collection("messages");
if (Meteor.isClient) {
// this will configure the sign up field so it
// they only need a username
Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY',
});
Template.messageForm.events({
// this event listener is triggered when they click on
// the post! button on the message form template
'click .js-save-message': function (event) {
var messageText = $('#message-text-input').val();
// notice how tihs has changed since the lsat time
// now we read the username from the Meteor.user()
var messageNickname = "Anon";
if (Meteor.user()) {
messageNickname = Meteor.user().username;
}
var message = {
messageText: messageText,
nickname: messageNickname,
createdOn: new Date()
};
// HERE is where you come in ....
// call a meteor method
// on the server here instead of
if (Meteor.isServer) {
Meteor.methods({ // defines a method, adds extra security layer to app
insertMessage: function () {
var doc, user, euser;
doc = Message.findOne();
if (!doc) {
return;
} // no logged in user, give up
// now I have a doc and possibly a user
user = Meteor.user().profile;
eusers = insertMessage.findOne({ docid: doc._id });
if (!eusers) {
eusers = {
docid: doc._id,
users: {},
};
}
user.lastEdit = new Date();
eusers.users[this.userId] = user;
insertMessage.upsert({ _id: eusers._id }, eusers);
}
}
)
}
// comment out this code, which won't work as we removed insecure...
//Messages.insert(message); // the insecure way of doing it
// ... put code here that calls the
Meteor.call('insertMesage', message, function (err, res) {
if (!res) {
alert('You need to log in!');
}
});
Template.header.helpers({
// HERE is another one for you - can you
// complete the template helper for the 'header' template
// called 'nickname' that
// returns the nickname from the Session variable?, if they have set it
nickname: function () {
if (Meteor.user()) {
return Meteor.user().username;
}
},
});
Template.messageList.helpers({
// this helper provides the list of messages for the
// messageList template
messages: function () {
return Messages.find({}, { sort: { createdOn: -1 } })
}
});
},
});
}
Here is the html file
<body>
{{>header}}
{{>nicknameForm}}
{{>messageList}}
{{>messageForm}}
</body>
<template name="header">
<h1>Welcome to M-Instant {{nickname}}</h1>
</template>
<template name="messageList">
{{#each messages}}
{{>messageItem}}
{{/each}}
</template>
<template name="messageItem">
<h3>{{nickname}} - {{messageText}}</h3>
</template>
<template name="nicknameForm">
<div class="form-group">
<label for="nickname-input">Nickname:</label>
<input type="text" class="form-control" id="nickname-input"
placeholder="Type message here...">
<button type="submit" class="btn btn-default js-set-nickname">Set my
nickname!</button>
</div>
</template>
<template name="messageForm">
<div class="form-group">
<label for="message-text-input">Message:</label>
<input type="text" class="form-control" id="message-text-input"
placeholder="Type message here...">
<button type="submit" class="btn btn-primary js-save-message">Post!
</button>
</div>
</template>
Here is the Methods file
Meteor.methods({
'insertMessage':function(message){
console.log("If you manage to call the method, you'll see this
message in the server console");
if (!Meteor.user()){
return;
}
else {
return Messages.insert(message);
}
}
})

vue.js alert pops instead of console.log or anything else

I was working on a Follow button and while trying to get things clear I used alert when I clicked my button, then I changed it to console.log instead of alert but still alert kept popping up. Then I did a text change instead of this but the alert keeps on popping. I already tried clearing cache or fresh migrate but still not working.
File: Follow.vue
<template>
<div class="container">
<button class="btn btn-primary ml-4" #click="followUser" v-text="buttonText"></button>
</div>
</template>
<script>
export default {
props: ['userId','follows'],
mounted() {
console.log('Component mounted.')
},
data: function () {
return {
status: this.follows
}
},
methods: {
followUser(){
axios.post('/follow/' + this.userId)
.then(response =>{
this.status = ! this.status;
});
;
},
computed: {
buttonText(){
return (this.status) ? 'Unfollow' : 'Follow';
}
}
}
}
</script>
File: index.blade.php
...ect...
<follow-me user-id="{{ $user->id }}" follows="{{ $follows }}"> </follow-me>
...ect...
File: ProfilesController.php
public function index(User $user)
{
$follows = (auth()->user()) ? auth()->user()->following->contains($user->id) : false;
return view('profiles.index', compact('user', 'follows'));
}
File: FollowsController.php
public function store(User $user){
return auth()->user()->following()->toggle($user->profile);
}
Run npm run watch , it will recompile your whole asset( any js or css file).
Don't forget to run npm run watch (or dev) to update your built assets.
About your button, replace
<button class="btn btn-primary ml-4" #click="followUser" v-text="buttonText"></button>
By
<button class="btn btn-primary ml-4" #click="followUser">{{ buttonText }}</button>

How to use v-if from global function

This is my vue component code
<div v-if="$can('employee-create')" class="card-tools">
<router-link to="/admin/addphonebook" class="btn btn-success">
Add New
<i class="fa fa-phone"></i>
</router-link>
</div>
This is resources/assets/js/mixins/Permissions.vue file
export default {
methods: {
$can(permissionName) {
let route = window.routes.permission;
axios.get(route+`/${permissionName}`)
.then((resounse)=> {
return true;
})
.catch((error)=> {
return false;
});
},
},
};
This is resources/assets/js/app.js to import the mixin
import Permissions from './mixins/Permissions';
Vue.mixin(Permissions);
The $can function returning true but the 'Add New' button is not showing
v-if don't get the return true value
Anyone can help me?
Thanks in advance
#Csaba Gergely solved your problem. When you get data from server $can method return true once for a second or less, but after call $can steel returning false. You can create a variable called it success and store the axios call result.
It must be something like this
<div v-if="success" class="card-tools">
<router-link to="/admin/addphonebook" class="btn btn-success">
Add New
<i class="fa fa-phone"></i>
</router-link>
</div>
export default {
data(){
return {
success:false
}
},
methods: {
$can(permissionName) {
let route = window.routes.permission;
axios.get(route+`/${permissionName}`)
.then((resounse)=> {
this.success = true;
//return true;
})
.catch((error)=> {
this.success = false;
//return false;
});
},
},
P.S. Bocsi #Csaba Gergely, ha elhappoltam eloled a kerdest :(

Find a matching value in Vue component

I have passed this collection (postFavourite) to my vue component via props.
[{"id":1,"user_id":1,"post_id":2,"created_at":"2018-07-24 09:11:52","updated_at":"2018-07-24 09:11:52"}]
How do I then check if any instance of user_id in the collection is equal to userId which is the current logged in user (also sent via props).
Tried
let pf = _.find(this.postFavourite, { "user_id": this.userId})
Keep getting undefined as the value of the pf variable even though this.userID is equal to 1.
New to JS and Vue.js so any help would be great.
Here is the vue component code.
<template>
<div>
<i v-show="this.toggle" #click="onClick" style="color: red" class="fas fa-heart"></i>
<i v-show="!(this.toggle)" #click="onClick" style="color: white" class="fas fa-heart"></i>
</div>
</template>
<script>
export default {
data() {
return {
toggle: 0,
}
},
props: ['postData', 'postFavourite', 'userId'],
mounted() {
console.log("Post is :"+ this.postData)
console.log("User id is: "+ this.userId)
console.log("Favourite Object is :" +this.postFavourite);
console.log(this.postFavourite.find(pf => pf.user_id == this.userId));
},
methods: {
onClick() {
console.log(this.postData);
this.toggle = this.toggle ? 0 : 1;
}
}
}
</script>
This is how I passed the props to vue
<div id="app">
<favorite :post-data="'{{ $post->id }}'" :post-favourite="'{{Auth::user()->favourite }}'" :user-id="'{{ $post->user->id }}'"></favorite>
</div>
I gave up on lodash and find and just messed around with the data in the chrome console to work out how to check the value I wanted.
Then I built a loop to check for the value.
If it found it toggle the like heart on of not leave it off.
This will not be the best way to solve this problem but I'm just pleased I got my first real vue component working.
<template>
<div>
<i v-show="this.toggle" #click="onClick" style="color: red" class="fas fa-heart"></i>
<i v-show="!(this.toggle)" #click="onClick" style="color: white" class="fas fa-heart"></i>
</div>
</template>
<script>
export default {
props: ['postData', 'postFavourite', 'userId']
,
data() {
return {
toggle: 0,
favs: [],
id: 0
}
},
mounted () {
var x
for(x=0; x < this.postFavourite.length; x++){
this.favs = this.postFavourite[x];
if(this.favs['post_id'] == this.postData) {
this.toggle = 1
this.id = this.favs['id']
}
}
},
methods: {
onClick() {
console.log(this.postData)
if(this.toggle == 1){
axios.post('favourite/delete', {
postid: this.id
})
.then(response => {})
.catch(e => {
this.errors.push(e)
})
}
else if(this.toggle == 0){
axios.post('favourite', {
user: this.userId,
post: this.postData
})
.then(response => {
this.id = response.data
})
.catch(e => {
this.errors.push(e)
})
}
this.toggle = this.toggle ? 0 : 1;
}
}
}
</script>
Where I pass my props.
<favorite :post-data="'{{ $post->id }}'"
:post-favourite="{{ Auth::user()->favourite }}"
:user-id="'{{ Auth::user()->id }}'"></favorite>
Thanks to all that tried to help me.
From just the code you provided, I see no issue. However lodash is not required for this problem.
Using ES2015 arrow functions
let pf = this.postFavourite.find(item => item.user_id === this.userId);
Will find the correct item in your array
You can read more about this function in the mdn webdocs
You can use find() directly on this.postFavourite like this:
this.postFavourite.find(pf => pf.user_id == this.userId);
Here is another way to do it that might help you as well.
[EDIT]
In order to use find() the variable needs to be an array, this.postFavourite is sent as a string if you didn't use v-bind to pass the prop thats what caused the error.
To pass an array or an object to the component you have to use v-bind to tell Vue that it is a JavaScript expression rather than a string. More informations in the documentation
<custom-component v-bind:post-favourite="[...array]"></custom-component>

Accessing Vue components data

I'm having trouble accessing data in Vue component I use prop to pass my data from view to component like this. I'm using Laravel.
<fav-btn v-bind:store="{{ $store }}"></fav-btn>
And my component looks like this:
<template>
<a href="#" class="btn-link text-danger" v-on:click="favorite">
<i v-bind:class="{ 'fa fa-heart fa-2x': isFavorited == true, 'fa fa-heart-o fa-2x': isFavorited == false }" class="" aria-hidden="true"></i>
</a>
</template>
<script>
export default {
props: ['store'],
data(){
return{
isFavorited: this.store.favoritable.isFavorited,
}
},
methods: {
favorite: function () {
this.AjaxRequest();
this.ToggleFav();
},
ToggleFav: function () {
this.isFavorited = !(this.isFavorited);
},
AjaxRequest: function () {
if (this.isFavorited)
{
axios.delete('stores/' + this.store.favoritable_id);
}
else {
axios.post('stores/' + this.store.favoritable_id);
}
}
}
}
</script>
In Vue devtools I can see all the objects in props but I can't access them the isFavorited always stays false. Am I accessing the objects attributes incorrectly?
You are doing it wrong. You shouldn't diractly mutate a value which is in store. You should write a mutator in the store file and change value by that. Here is the docs.
https://vuex.vuejs.org/en/mutations.html

Resources