Vue update variable and refresh in another component? - vue.js

I have form component and in catch part I push errors tu my StatusBar component:
}).catch(error => {
StatusBar.methods.handleErrors(error.response.data)
})
In my StatusBar component I want to show this errors like:
handleErrors(newErrors) {
this.errors = [];
if (newErrors.errors) {
for (var i in newErrors.errors) {
this.errors.push(newErrors.errors[i][0]);
}
}
}
I tried in view area to add:
<div class="alert alert-danger" v-for="error in this.errors">{{ error }}</div>
The problem is in console output I see the correct result, but in the view area is nothing updated. I tried also with v-model but nothing was updated.
How can I push results from loop automatically/update to alert?

Related

Vue js error message only shows once. Trying to figure out how to show it everytime there's an error

I'm new to Vue, but I'm trying to figure out how to solve this issue
I have a reference to a component here.
<notification-component v-if="error" :error="error"><notification-component>
I have a method that does an axios call and I'm checking the resonse.data['responseCode'] == '500'
if it is 500 then create the variable error like this
if(response.data['responseCode'] == "500"){
this.error = response.data['applicationCode']['message'];
}
The problem is that if I run the axios call once, it works great! It will run display the error just fine. If I run it again (Even those the error exists), it doesn't show the error message. I hope this makes sense. It's like I need the V-if but maybe something with the state.
Thanks,
Dan
In your notification component add v-if and close button with hide function
<div class="ui message" :class="type" v-if="!hidden">
<i class="close icon" #click="hide"></i>
<div class="header">
{{header}}
</div>
<slot></slot>
</div>
...
data() {
return {
hidden: false
}
},
methods: {
hide() {
this.hidden = true
}
}
But If message is automatically closed (with some delay), then you should destroy component and emit changes in parent.

Vue.js this.$refs empty due to v-if

I have a simple Vue component that displays an address, but converts into a form to edit the address if the user clicks a button. The address field is an autocomplete using Google Maps API. Because the field is hidden (actually nonexistent) half the time, I have to re-instantiate the autocomplete each time the field is shown.
<template>
<div>
<div v-if="editing">
<div><input ref="autocomplete" v-model="address"></div>
<button #click="save">Save</button>
</div>
<div v-else>
<p>{{ address }}</p>
<button #click="edit">Edit</button>
</div>
</div>
</template>
<script>
export default {
data() {
editing: false,
address: ""
},
methods: {
edit() {
this.editing = true;
this.initAutocomplete();
},
save() {
this.editing = false;
}
initAutocomplete() {
this.autocomplete = new google.maps.places.Autocomplete(this.$refs.autocomplete, {});
}
},
mounted() {
this.initAutocomplete();
}
}
I was getting errors that the autocomplete reference was not a valid HTMLInputElement, and when I did console.log(this.$refs) it only produced {} even though the input field was clearly present on screen. I then realized it was trying to reference a nonexistent field, so I then tried to confine the autocomplete init to only when the input field should be visible via v-if. Even with this, initAutocomplete() is still giving errors trying to reference a nonexistent field.
How can I ensure that the reference exists first?
Maybe a solution would be to use $nextTick which will wait for your DOM to rerender.
So your code would look like :
edit() {
this.editing = true;
this.$nextTick(() => { this.initAutocomplete(); });
},
Moreover if you try to use your this.initAutocomplete(); during mounting it cannot work since the $refs.autocomplete is not existing yet but I'm not sure you need it since your v-model is already empty.
I think it's because your "refs" is plural
<input refs="autocomplete" v-model="address">
It should be:
<input ref="autocomplete" v-model="address">

React Motion: simple chaining

I'm using react, mobx and I need to animate things.
I want to do a simple animation chaining: when the first animation ends, the second starts.
As use case think of a section templates: every time the user change the section, the current section fade out and then the next section fade in.
Any hints?
Regardless react-motion or any other library, you can always use onAnimationEnd animation event listener .
With this method you are able to detect when css animation ends on related html element and execute method function.
Then you can choose what to do , for example using setState():
animation1 = () => {
this.setState({
animation1: true
})
}
animation2 = () => {
this.setState({
animation2: true
})
}
animation3 = () => {
this.setState({
animation3: true
})
}
render() {
return (
<div>
<div onAnimationEnd={this.animation1}>
First animation
</div>
<div onAnimationEnd={this.animation2}>
Second animation
</div>
<div onAnimationEnd={this.animation3}>
Third animation
</div>
</div>
)
}

Hide an item when is deleted with this.$http.delete()

I have website build with VueJS on frontend and I want to hide each item that is deleted.
I have in store.js a property eventIsActive set to true:
export const store = new Vuex.Store({
state: {
eventIsActive: true
}
})
In a ShowItems.vue(grid version) I have a the delete method where I set the eventIsActive to false:
removeEvent() {
this.$http.delete('/event/' + item)
.then((response) => {
this.$store.state.eventIsActive = false;
this.$router.push('/events');
})
.catch((error) => {
alertify.error('Error', error);
})
}
On the same page I have the computed method for this property eventIsActive:
computed: {
getActiveEvent() {
return this.$store.state.eventIsActive;
}
}
On the HTML for this page I use the method from computed to hide the deleted component.
<template>
<div class="col-6 col-lg-4" v-if="getActiveEvent">
<p>{{itemTitle}}</p>
<p>{{itemSubtitle}}</p>
</div>
</template>
The problem is that when I delete an item, the rest of items are hidden, not only the one that is deleted.
Before I just used a simple eventIsActive: true in data() and set it to false in the removeEvent(). Was easier to use it, but because I have ShowItems.vue(list version), too, if I delete an Item in grid version, in the list version will still be there, until I refresh the page.
Can someone help me in this direction?
Vuex state is a global state that is shared by all components in the app.
So when you change eventIsActive all elements get the same state (true/false) and act accordingly.
Since showing/hiding an item is related to that specific item state, you need to have a local state for each item and change only it.
so in the data attribute of the component, add an active flag and use it instead:
data () {
....
active: true
}
....
removeEvent() {
this.$http.delete('/event/' + item)
.then((response) => {
this.active = false;
this.$router.push('/events');
})
.catch((error) => {
alertify.error('Error', error);
})
}
....
<template>
<div class="col-6 col-lg-4" v-if="active">
<p>{{itemTitle}}</p>
<p>{{itemSubtitle}}</p>
</div>
</template>

REACT - defaultChecked don't render check attribute on second load

I got my component who won't check the radio when i go to the /view/:id for the second time. I started in my list component with react-router at the index of the site, i click on the view button of an element, the radio is checked, i return in my list and go to another or the same element and it's not checked anymore. When i inspect the component in the React developer tool, the radio has the defaultChecked=true property.
import React from 'react';
import { connect } from 'react-redux';
class LicenseRadios extends React.Component {
buildRadios() {
let { licenses, activeValue } = this.props;
return licenses.map(license => {
let checked = false;
if(activeValue !== undefined && activeValue === license.id){
checked = true;
}
return (
<div key={license.id} className="col l2">
<p>
<input name="license" type="radio" id={'licenseRdo_' + license.id} value={license.id} defaultChecked={checked} />
<label htmlFor={'licenseRdo_' + license.id}>{license.label}</label>
</p>
</div>
);
});
}
render() {
return (
<div className="row">
{this.buildRadios()}
</div>
);
}
}
export default LicenseRadios;
I tried to change the defaultChecked for the checked attribute, but it require an onChange event. I don't understand this problem. Can anybody help me please?
Thank you
The defaultChecked prop is only used during initial render. If you need to update the value in a subsequent render, you will need to use an onChange function to handle value changes.
Check out controlled components in the docs to better understand the problem you're having.
use "undefined" for initial value for defaultChecked and re-render by setting it to true or false
const Example = () => {
[checked,setChecked] = useState(undefined);
useEffect(()=>{
// fetch data
setChecked(true);
});
return (
<input type="checkbox" defaultChecked={checked} onClick={(e)=> changeValue(e)}/>
);
}