How to implement dexie.js in Vue Chrome extension mv3 - vue.js

I have this code in my vue powered chrome extension
import dexie from 'dexie'
export default {
name: 'NewTab',
setup(){
return {
db: new dexie('storeManager', { autoOpen: true })
}
},
data() {
return {
sizes: [
'XS',
'S',
'M',
'L',
'XL',
'XXL',
'XXXL'
],
itemName: null,
itemPrice: null,
selectedSize: null,
savedItems: [],
pz: null,
}
},
mounted() {
},
methods: {
addItem(){
//db.version(1).stores({
// atricoli: "++id, name, size, color, pz, price"
//});
console.log(db)
console.log(this.itemName, this.selectedSize, this.pz)
this.savedItems.push({
name: this.name,
size: this.selectedSize,
pz: this.pz
})
}
}
}
I want to use dexie.js as database to store the input that the user will enter in the form I have in my new tab page. I've added the autoOpen option, to load the db but I'm not sure how to setup the table I need. Is correct to call the stores method every time the addItem is called?

Related

react native redux toolkit how can I pass data to array?

How can I pass data to array (redux toolkit) ?
I tried this but not working.
I have an array of shippers:
const shipper = [
{
type: 'NORMAL',
item: {
id: 1,
name: 'SHIPPER1',
}
},
{
type: 'NORMAL',
item: {
id: 2,
name: 'SHIPPER2',
}
},
{
type: 'NORMAL',
item: {
id: 3,
name: 'SHIPPER3',
}
},
{
type: 'NORMAL',
item: {
id: 4,
name: 'SHIPPER4',
}
},
{
type: 'NORMAL',
item: {
id: 5,
name: 'SHIPPER5',
}
},
];
I want to add each item to the reducer array. Like this without redux.
setShippers(prevState => {
return [...prevState, shipper];
});
But I want it in Redux Toolkit:
slice/shipper.js
import { createSlice } from "#reduxjs/toolkit";
const createProductShipper = createSlice({
name: "createProductShipper",
initialState: {
shippers: []
},
reducers: {
AddProductShipper(state, action) {
state.shippers = [...state.shippers, action.payload];
},
}
});
export const { AddProductShipper } = createProductShipper.actions;
export default createProductShipper.reducer;
...
dispatch(AddProductShippers({id, shipper});
...
..................................................................................................................................................................................................................
I’m a bit confused about whether the shipper variable is an array or a single shipper — and I suspect that you are too.
Your “without redux” example would be the correct way to add a single shipper to the array. If shipper is an array then you’ll want to spread both prevState and shipper:
setShippers(prevState => [...prevState, …shipper]);
The same goes for the redux reducer.
But the way that you are calling the dispatch seems strange:
dispatch(AddProductShippers({id, shipper}));
This will dispatch an action whose payload has properties id and shipper. Is that what you want? What is the id property: the product id or the shipper id?
Assuming that the product id is irrelevant (it appears nowhere in your slice) and that you want to add an array of shippers, your code might look something like this:
dispatch(AddProductShippers(arrayOfShippers));
AddProductShipper(state, action) {
state.shippers = [...state.shippers, …action.payload];
}
Or
AddProductShipper(state, action) {
state.shippers.push(…action.payload);
}

Accessing data variables in Vue method for a loop

I want to access the data() variables
data () {
return {
name: '',
manufacturerIds: null,
supplierIds: null,
categoryIds: null,
productIds: null,
minPrice: 100,
maxPrice: 0,
priority: 0,
enable: true,
active: true,
minMargin: 0,
position: 0,
isLoading: false,
suppliers: [],
categories: [],
manufacturers: []
}
},
in a method in the same component. I know we can call it individually as property this.someVariable but what I want is to loop over all the variables to reset its values. So instead of calling them all one by one, I was thinking to loop over the data() and then assign it a null value (to reset).
I already tried this.data and this.getData() and this.data() but neither of them works.
It's a bad idea to reset the properties one by one because you will need to check each one of them to determine what value you need to set it to (null, array, boolean, etc). Do you really want to have if checks for all the properties?
A better way is to just clone the object before you make any changes to it and then just reset all the properties at once:
Method 1: store reset data locally
data () {
return {
// Add a property for storing unchanged data
defaultData: {},
data: {}
name: '',
manufacturerIds: null,
supplierIds: null,
categoryIds: null,
productIds: null,
minPrice: 100,
maxPrice: 0,
priority: 0,
enable: true,
active: true,
minMargin: 0,
position: 0,
isLoading: false,
suppliers: [],
categories: [],
manufacturers: []
}
},
created: {
// Clone data before you make any changes
this.cloneData()
},
methods: {
cloneData () {
// Method 1 (better way, but requires lodash module)
const clonedData = lodash.cloneDeep(this.$data)
// Method 2 (bad choice for complex objects, google "deep clone JS" to learn why)
const clonedData = JSON.parse(JSON.stringify(this.$data))
// Store the cloned data
this.defaultData = clonedData
},
resetData () {
// Reset the values using cloned data
this.$data = this.defaultData
}
}
Method 2: store reset data in Vuex store
data () {
return {
name: '',
manufacturerIds: null,
supplierIds: null,
categoryIds: null,
productIds: null,
minPrice: 100,
maxPrice: 0,
priority: 0,
enable: true,
active: true,
minMargin: 0,
position: 0,
isLoading: false,
suppliers: [],
categories: [],
manufacturers: []
}
},
created: {
// Clone data before you make any changes
this.cloneData()
},
methods: {
cloneData () {
// Method 1 (better way, but requires lodash module)
const clonedData = lodash.cloneDeep(this.$data)
// Method 2 (bad choice for complex objects, google "deep clone JS" to learn why)
const clonedData = JSON.parse(JSON.stringify(this.$data))
// Set the cloned data object to Vuex store
this.$store.commit('SET_DEFAULT_DATA ', clonedData)
},
resetData () {
// Reset the values using cloned data
this.$data = this.$store.state.defaultData
}
}
store.js
state: {
defaultData: {}
},
mutations: {
SET_DEFAULT_DATA (state, value) {
state.defaultData = value
}
}
What if you made an array of all the proporties in the data-method?
Example:
data() {
name: '',
manufacturerIds: null,
supplierIds: null
dataArray: [name, manufacturerIds, supplierIds]
}
and then call a method which loops over dataArray?

Getting documents with ID from firstore collection

While using Firestore, vuefire, vue-tables-2, I stuck getting document's id.
My data structure is as below.
Here is my code.
<v-client-table :columns="columns" :data="devices" :options="options" :theme="theme" id="dataTable">
import { ClientTable, Event } from 'vue-tables-2'
import { firebase, db } from '../../firebase-configured'
export default {
name: 'Devices',
components: {
ClientTable,
Event
},
data: function() {
return {
devices: [],
columns: ['model', 'id', 'scanTime', 'isStolen'],
options: {
headings: {
model: 'Model',
id: 'Serial No',
scanTime: 'Scan Time',
isStolen: 'Stolen YN'
},
templates: {
id: function(h, row, index) {
return index + ':' + row.id // <<- row.id is undefined
},
isStolen: (h, row, index) => {
return row.isStolen ? 'Y': ''
}
},
pagination: {
chunk: 5,
edge: false,
nav: 'scroll'
}
},
useVuex: false,
theme: 'bootstrap4',
template: 'default'
}
},
firestore: {
devices: db.collection('devices')
},
};
My expectation is devices should id property as vuefire docs.
But array this.devices didn't have id field even if I check it exist it console.
Basically, every document already has id attribute, but it's non-enumerable
Any document bound by Vuexfire will retain it's id in the database as
a non-enumerable, read-only property. This makes it easier to write
changes and allows you to only copy the data using the spread operator
or Object.assign.
You can access id directly using device.id. But when passing to vue-tables-2、devices is copied and lost id non-enumerable attribute.
I think you can workaround using computed property
computed: {
devicesWithId() {
if (!this.devices) {
return []
}
return this.devices.map(device => {
...device,
id: device.id
})
}
}
Then, please try using devicesWithId in vue-tables-2 instead.

How to store multiple api's data with VueX and add properties to the response

Suppose i want to store data from multile Api requests - when the App is instantiated,
and i also want to add properties to each response
Here is the url of the api 'http://api.open-notify.org/iss-pass.json?lat=LAT&lon=LON'
Updated
I want to instantiated the app with all the data from a couple of get requests - so i'm looping all the requests - that part is works fine , but i also want to be able to add to response.data.response object properties from the cities array, so the finale result will be :
cities: [{
id: 0,
cityName: 'Select a city',
stuff from response.data...
},......
Here is the main part of the Api call
const store = new Vuex.Store({
state: {
satelliteData: [],
dataObj:[],
loading: true,
cities: [{
id: 0,
cityName: 'Select a city',
cityLocation: null
},
{
id: 1,
cityName: 'Tel Aviv',
cityLat: '32.0853',
cityLon: '34.7818'
},
{
id: 2,
cityName: 'London',
cityLat: '51.5074',
cityLon: '-0.1278'
},
{
id: 3,
cityName: 'New York',
cityLat: '40.7128',
cityLon: '-74.0060'
},
],
},
actions: {
loadData({commit}) {
for(var i=0; i<this.state.cities.length; i++){
var currData = this.state.cities[i];
if(!!this.state.cities[i].hasOwnProperty('cityLat'))
axios.get(URL, {
params: {
lat: this.state.cities[i].cityLat,
lon: this.state.cities[i].cityLon,
},
}).then((response) => {
Here is where i want to be able to access the Cities array
/* var cities = this.$store.state.cities;
console.log(cities) */
commit('updateSatelliteData', response.data.response)
commit('changeLoadingState', false)
})
}
}
},
Fiddle
Since i'm new to Vue - i'm sure that there are a couple of mistakes here. Thanks

Vue.js - Element UI - HTML message in MessageBox

I'm using vue-js 2.3 and element-ui. This question is more specific to the MessageBox component for which you can find the documentation here
Problem
I'd like to be able to enter html message in the MessageBox
More specifically I would like to display the data contained in dataForMessage by using a v-for loop.
Apparently, we can insert vnode in the message but I have no idea where to find some information about the syntax.
https://jsfiddle.net/7ugahcfz/
var Main = {
data:function () {
return {
dataForMessage: [
{
name:'Paul',
gender:'Male',
},
{
name:'Anna',
gender:'Female',
},
],
}
},
methods: {
open() {
const h = this.$createElement;
this.$msgbox({
title: 'Message',
message: h('p', null, [
h('span', null, 'Message can be '),
h('i', { style: 'color: teal' }, 'VNode '),
h('span', null, 'but I would like to see the data from '),
h('i', { style: 'color: teal' }, 'dataForMessage'),
])
}).then(action => {
});
},
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
I think this is what you want.
methods: {
open() {
const h = this.$createElement;
let people = this.dataForMessage.map(p => h('li', `${p.name} ${p.gender}`))
const message = h('div', null, [
h('h1', "Model wished"),
h('div', "The data contained in dataForMessage are:"),
h('ul', people)
])
this.$msgbox({
title: 'Message',
message
}).then(action => {
});
},
}
Example.
You can also use html directly and convert to vnodes by using domProps:
const html = '<div><h1>Model wished</h1><div>The data contained in dataForMessage are:</div><ul><li>Paul Male</li><li>Anna Female</li></ul></div>'
const message = h("div", {domProps:{innerHTML: html}})
(The above is simplified without the loop. Just to get the idea)
Fiddle