How to refresh datatables with new data in Laravel vuejs? - vue.js

I am using datatables 1.10.19 in vue js. .How can I refresh the table after inserting new data into data base ? I used clear, destroy and draw but nothing works.Here is my entire code.
the data is not loaded in to datatable until the page is refreshed
table() { this.$nextTick(() => {
$('#sampleTable').DataTable();
})
},
get() {
axios.get('api/user').then(res => {
this.users = res.data
// console.log("after: " + this.users);
this.table()
});
axios.get("api/getRoles").then(({
data
}) => (this.roles = data));
// if (refreshIt == true) {
// this.retable();
// } else {
this.table();
// }
$(".selectpicker").selectpicker();
},
create() {
// this.validation();
this.form.post('api/user').then(() => {
$("#addnew").modal("hide");
toast.fire({
icon: "success",
type: "success",
title: "Information Created Successfully!"
});
Fire.$emit("refreshPage");
this.form.reset();
})
.catch(er => {
console.log(er);
});
created() {
// we call the show function here to be executed
this.get();
Fire.$on("refreshPage", () => {
this.get();
});}

I found the solution I destroy the datable in the create function $('#sampleTable').DataTable().destroy(); and then create it back like below
create() {
this.form.post('api/user').then(() => {
$("#addnew").modal("hide");
toast.fire({
icon: "success",
type: "success",
title: "Information Created Successfully!"
});
$('#sampleTable').DataTable().destroy();// here I destroyed the table
Fire.$emit("refreshPage");// here I recreated the table
this.form.reset();
})
.catch(er => {
console.log(er);
});
},

Related

Vue.js updating text in a modal

I have a modal and I am trying to dynamically update the text.
in my data
return {
count: {
value: 5
},
}
then I have a method
bulkUserImport: function() {
this.isLoading = true;
let _this = this;
axios.post('bulkUpdate', {'csv': this.importData})
.then((r) => console.log(r))
.then(() => this.isLoading = false)
.then(function() {
_this.$modal.show('dialog', {
title: 'Adding your new Clients',
text: `Jobscan is now provisioning your accounts, page will refresh in ${_this.count.value} seconds.`,
buttons: [
{
default: true,
handler: () => _this.$emit('close'),
}
]
});
_this.test()
})
.then(() => this.reloadClients());
},
Then the test method
test: function(){
if(this.count.value > 0){
this.count.value = this.count.value - 1;
console.log(this.count.value);
let temp = this;
setTimeout(function(count){
temp.test();
}, 1000);
}
},
In the text in the modal I have a variable _this.count.value that prints out 5. Then I have a call to _this.test() to update the variable.
In test(). I console.log the results and the number does go down
However, it is not updating the _this.count.value in the text. What am I doing wrong?
Here is the modal

How to turn vue.js method inside a component to a created method

I am working with a vue.js code base where a method inside the component is being called by onclick()
instead I want the method to just be ran when the page loads rather than be called by onclick. Reading the vue.js docs I believe I need to use a vue method called created(), Can I simply replace 'method' with 'created' or what exactly do I need to do to run this method on page load.
<script>
Vue.component('job-execs', {
delimiters: [ '[[', ']]' ],
props: ['job'],
data: function() {
return {
showExecs: false,
build_ids: []
}
},
methods: {
jobExecs() {
url = "api/v2/exec?" + this.job.api_url + "&limit=10"
fetch(url)
.then(response => response.json())
.then(body => {
for(i=0; i<body.length; i++){
start_date = JSON.stringify(body[i].time_start)
start_date = start_date.match(/"?(.*)T(.*)/)[1];
this.build_ids.push({
'id': JSON.stringify(body[i].id),
})
}
})
.catch( err => {
console.log('Error Fetching:', url, err);
return { 'failure': url, 'reason': err };
});
}
},
as the lifecycle of vuejs app, to first thing vuejs do is to run the created,
so in your case, you should put the jobExecs function within created hook.
for more information check Instance Lifecycle Hooks Vuejs doc
in that case, your component will be like below :
<script>
Vue.component('job-execs', {
delimiters: [ '[[', ']]' ],
props: ['job'],
data: function() {
return {
showExecs: false,
build_ids: []
}
},
created() {
this.jobExecs();
},
methods: {
jobExecs() {
url = "api/v2/exec?" + this.job.api_url + "&limit=10"
fetch(url)
.then(response => response.json())
.then(body => {
for(i=0; i<body.length; i++){
start_date = JSON.stringify(body[i].time_start)
start_date = start_date.match(/"?(.*)T(.*)/)[1];
this.build_ids.push({
'id': JSON.stringify(body[i].id),
})
}
})
.catch( err => {
console.log('Error Fetching:', url, err);
return { 'failure': url, 'reason': err };
});
}
},

Vuex update state by using store actions

I have two functions in my store, one that gets data by calling API and one that toggles change on cell "approved". Everything working fine, except that when I toggle this change it happens in database and I get the response that it is done but It doesn't update on UI.
I am confused, what should I do after toggling change to reflect change on UI, should I call my API from .then or should I call action method responsible for getting data from server.
export default {
state: {
drivers: {
allDrivers:[],
driversError:null
},
isLoading: false,
token: localStorage.getItem('token'),
driverApproved: null,
driverNotApproved: null
},
getters: {
driversAreLoading (state) {
return state.isLoading;
},
driverError (state) {
return state.drivers.driversError;
},
getAllDrivers(state){
return state.drivers.allDrivers
}
},
mutations: {
getAllDrivers (state) {
state.isLoading=true;
state.drivers.driversError=null;
},
allDriversAvailable(state,payload){
state.isLoading=false;
state.drivers.allDrivers=payload;
},
allDriversNotAvailable(state,payload){
state.isLoading=false;
state.drivers.driversError=payload;
},
toggleDriverApproval(state){
state.isLoading = true;
},
driverApprovalCompleted(state){
state.isLoading = false;
state.driverApproved = true;
},
driverApprovalError(state){
state.isLoading = false;
state.driverError = true;
}
},
actions: {
allDrivers (context) {
context.commit("getAllDrivers")
return new Promise((res,rej)=>{
http.get('/api/admin/getAllDrivers').then(
response=>{
if (response.data.success){
let data=response.data.data;
data=data.map(function (driver) {
return {
/* response */
};
});
context.commit("allDriversAvailable",data);
res();
}else {
context.commit("allDriversNotAvailable",response.data)
rej()
}
})
.catch(error=>{
context.commit("allDriversNotAvailable",error.data)
rej()
});
});
},
toggleDriverApproval (context, payload){
return new Promise((res, rej)=>{
http.post("/api/admin/toggleDriverApproval",{
driver_id: payload
})
.then( response => {
context.commit('driverApprovalCompleted');
res();
}).catch( error =>{
context.commit('driverApprovalError');
rej()
})
})
}
}
}
and here is the code on the view, I wrote the necessary code for better clarification of the problem
export default {
name: 'Drivers',
data: () => ({
data: [],
allDrivers: [],
driversErrors: []
}),
created() {
this.$store
.dispatch('allDrivers')
.then(() => {
this.data = this.$store.getters.getAllDrivers
})
.catch(() => {
this.errors = this.$store.getters.driverError
})
},
computed: {
isLoading() {
return this.$store.getters.driversAreLoading
}
},
methods: {
verify: function(row) {
console.log(row)
this.$store.dispatch('toggleDriverApproval', row.id).then(() => {
this.data = this.$store.getters.getAllDrivers
console.log('done dis')
})
},
},
}
if I understand your issue, you want the UI displaying your data to change to the updated data after making a post request.
If you are using Vuex you will want to commit a mutation, and use a getter display the data.
I am not sure how your post request is being handled on the server but if successful typically you would send a response back to your front end with the updated data, and commit a mutation with the updated data.
Example:
Make a Post request
toggleDriverApproval (context, payload){
return new Promise((res, rej)=>{
http.post("/api/admin/toggleDriverApproval",{
driver_id: payload
})
.then( response => {
context.commit('driverApprovalCompleted', response.data);
res();
}).catch( error =>{
context.commit('driverApprovalError', error.response.data);
rej()
})
})
}
If succesful commit the mutation
.then( response => {
context.commit('driverApprovalCompleted', response.data);
res();
})
response.data being your data you want to mutate the state with.
Mutation Example:
customMutation(state, data) {
state.driverApproval = data
}
Getter Example:
driver(state) {
return state.driverApproval
}
displaying the getter in a template
<template>
<div v-if="driver">{{driver}}</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: Example,
computed: {
driver() {
return this.$store.getters.driver
},
// or use mapGetters
...mapGetters(['driver'])
}
}
</script>
more examples can be found at Vuex Docs

pass computed property as method parameter?

So I have a store with values:
export const store = new Vuex.Store({
state: {
selectedGradeId: null,
},
getters:{
selectedGradeId: state => {
return state.selectedGradeId
},
},
mutations:{
SET_SELECTED_GRADE_ID(state, gradeid){
state.selectedGradeId = gradeid
},
CLEAR_SELECTED_GRADE_ID(state){
state.selectedGradeId = null
},
},
actions:{
loadStudentsForGrade (gradeId) {
return new Promise((resolve, reject) => {
axios.get('/students/'+gradeId)
.then((response)=>{
... do stuff
resolve(response)
}, response => {
reject(response)
})
})
},
}
})
and inside my component i basically have a select that loads the student list for the particular grade:
<select id="grades" name="grades" v-model="selectedGradeId" #change="loadStudentsForGrade(selectedGradeId)"
methods: {
loadStudentsForGrade(gradeId) {
this.$store.dispatch('loadStudentsForGrade', {gradeId})
.then(response => {
}, error => {
})
},
},
computed: {
selectedGradeId: {
get: function () {
return this.$store.getters.selectedGradeId;
},
set: function (gradeId) {
this.$store.commit('SET_SELECTED_GRADE_ID', gradeId);
}
},
}
when the 'loadStudentsForGrade' method is called in my component, it takes 'selectedGradeId' as a parameter, which is a computed property.
Now the problem I have is that inside my store, the action 'loadStudentsForGrade' gets an object( i guess computed?) instead of just the gradeid
object i get is printed to console:
{dispatch: ƒ, commit: ƒ, getters: {…}, state: {…}, rootGetters: {…}, …}
The first parameter of your action is the store, and the second the payload.
so you should do :
actions:{
// here: loadStudentsForGrade (store, payload) {
loadStudentsForGrade ({ commit }, { gradeId }) {
return new Promise((resolve, reject) => {
axios.get('/students/'+gradeId)
.then((response)=>{
//... do stuff
//... commit('', response);
resolve(response)
}, response => {
//... commit('', response);
reject(response)
})
})
},
}
Related page in the docs :
https://vuex.vuejs.org/en/actions.html#dispatching-actions

How to avoid refetching data in React-native

I am using react-native-navigation-drawer. I fetch data from url (inside componentDidMount) to render first page. Then I go to second/third (other) pages. When I reselect/choose First Page again. It refetch data from url. How I can keep that data so that I can avoid fetching url again and again until user click on refresh button. Any help, please. I tried fetching data in parent view and passProps but if I do so, I can't refresh data.
getInitialState: function() {
return {
dataSource: null,
loaded: false,
networkError : false,
};
},
componentDidMount: function() {
if(this.props.firstTime){//This is used to fetch data only the in first time.
this.fetchData(); //call function to fetch data from url
}
console.log("Issue View First Time :: " + this.props.firstTime);
},
fetchData: function() {
fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource: responseData, //Want to keep this information to render again.
loaded: true,
});
})
.catch((error) => {
console.warn('error ::: ' + error);
this.setState({
networkError: true, //used to render error View
});
})
.done(()=> {
});
},
This is a dump question. I figured it out.
I declare a variable and set state of dataSource with that variable.
var KEEPED_DATA = [];
var FirstView = React.createClass({
getInitialState: function() {
return {
dataSource: KEEPED_DATA,
networkError : false,
};
},
componentWillMount: function() {
if(!KEEPED_DATA.length){
this.fetchData();
}
},
fetchData: function() {
//Fetching data from url
KEEPED_DATA = responseData;
},
render: function() {
//render
});