2017-10-18 3 views
0

J'ai une application électronique qui utilise mysql package pour me connecter directement à ma base de données. Ce que j'essaie de faire est de stocker connection objet créé avec mysql.createConnection() dans l'état Vuex. Ensuite, je veux récupérer des nombres de la base de données en utilisant cet objet.Objet de connexion Vuex et mysql: Ne pas muter état de magasin vuex en dehors des gestionnaires de mutation

J'ai obtenu ce code pour le magasin Vuex:

const state = { 
    connectionObject: null, 
    numbers: [], 
}; 

const getters = { 
    getNumbers: state => state.numbers, 
    getConnectionObject: state => state.connectionObject, 
}; 

const mutations = { 
    SET_NUMBERS(state, numbers) { 
    state.numbers = Object.assign({}, numbers); 
    }, 
    SET_CONNECTION_OBJECT(state, connection) { 
    state.connectionObject = connection; 
    }, 
}; 

const actions = { 
    fetchNumbers({ state, commit }) { 
    const connection = _.cloneDeep(state.connectionObject); 
    connection.query({ 
     sql: 'SELECT * FROM `numbers`', 
     timeout: 40000, 
    }, async (error, results) => { 
     if (error instanceof Error) { 
     throw new Error(error); 
     } 
     commit('SET_NUMBERS', await results); 
    }); 
    }, 
    connectToDatabase({ commit }, data) { 
    const connection = mysql.createConnection(data); 
    return new Promise((resolve, reject) => { 
     connection.connect(async (err) => { 
     if (err) { 
      return reject(err); 
     } 
     commit('SET_CONNECTION_OBJECT', await connection); 
     commit('SET_DB_CONNECTION_STATE', data); 
     return resolve(connection); 
     }); 
    }); 
    }, 
}; 

Ce qui se passe est une fois que je lance le code que je reçois Error in callback for watcher "function() { return this._data.$$state }": "Error: [vuex] Do not mutate vuex store state outside mutation handlers." et cette erreur est levée lorsque connection.query() est exécuté.

J'ai du mal à comprendre pourquoi cela ne fonctionne pas car je clone connectionObject d'état après tout. On dirait que ses observateurs sont également clonés. Y a-t-il un moyen de l'éviter?

Répondre

0

L'objet de connexion est hautement modifiable, il ne peut pas être stocké. Chaque connexion que vous effectuez modifie les propriétés de l'objet de connexion. Je ne stockerais que les retours dans le stockage, la mise à jour des données dans les actions et l'objet connectionobject devrait être rendu accessible sur vuex, attention à le rendre global, cela rendrait votre application plus facile à pirater. Une façon de le rendre accessible est de simplement déclarer une variable à côté de l'état.

Si vous avez besoin de plus de conseils, il serait très utile de savoir quel paquet SQL vous avez utilisé pour vous donner du code.

+0

Mais je suis toujours curieux pourquoi exactement j'ai eu cette erreur. Quant à déclarer la variable 'connection' en plus de l'état, c'est ce que j'ai fait quand je n'ai pas réussi à le stocker dans l'état. J'utilise mysqljs/mysql paquet btw. –

+1

Je pense que vous êtes confus parce que vous n'avez jamais rencontré un edgecase où underscores deepcopy ne fonctionne pas;) Disons que vous faites une requête à votre serveur SQL et il vous répond même si vous copiez l'objet connexion tous les autres objets de connexion recive le awsner, il utilisera quelque chose comme un identifiant de thread pour identifier quel objet est l'évocateur de la requête et en deepcopying la connexion il a le même thread Id que la connexion dans l'état, entraînant une mutation sur les deux. https://github.com/mysqljs/mysql/blob/master/lib/Connection.js –