JavaScript warning: Assignment to property of function parameter - javascript

I compiled vue-flash-message component from sources and got the following warning:
✘ http://eslint.org/docs/rules/no-param-reassign Assignment to property of function parameter 'Vue'
src\components\vue-flash-message\index.js:173:5
Vue.prototype[options.storage] = FlashBus;
in the following code:
export default {
install(Vue, config = {}) {
const defaults = {
method: 'flash',
storage: '$flashStorage',
createShortcuts: true,
name: 'flash-message',
};
const options = Object.assign(defaults, config);
...
const FlashBus = new Vue({
data() {
return {
storage: {
},
};
},
methods: {
flash(msg, type, opts) {
return new FlashMessage(FlashBus, msg, type, opts);
},
push(id, message) {
Vue.set(this.storage, id, message);
},
destroy(id) {
Vue.delete(this.storage, id);
},
destroyAll() {
Vue.set(this, 'storage', {});
},
},
});
...
Vue.prototype[options.storage] = FlashBus;
...
},
};
is it possible to correct the code and make it compile without warnings?

This is not an issue.
You have an ES Lint rule setup for no-param-reassign. This conflicts with Vue's way of creating plugins, where you are directed to write to the prototype directly. You can see my statement reinforced here
Your only choice is to fork that project, and ignore the line with your linter if it's bugging you that much.

Related

Passing a variable between plugins in Rollup

How can I pass a variable between plugins in Rollup?
What I've tried:
// plugin-a.js
const pluginA = () => {
return {
name: 'pluginA',
async options(options) {
options.define = options.define || {};
options.define['foo'] = 'bar';
}
}
}
// plugin-b.js
const pluginB = (options = {}) => {
return {
name: 'pluginB',
buildStart: async (options) => {
console.log(options)
}
}
}
I'm getting a warning:
(!) You have passed an unrecognized option
Unknown input options: define. Allowed options: acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileOps, maxParallelFileReads, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch
It seems passing data should be done by what Rollup refers to as Direct plugin communication. This is working for me. I feel this is very hard coupled though.
function parentPlugin() {
return {
name: 'parent',
api: {
//...methods and properties exposed for other plugins
doSomething(...args) {
// do something interesting
}
}
// ...plugin hooks
};
}
function dependentPlugin() {
let parentApi;
return {
name: 'dependent',
buildStart({ plugins }) {
const parentName = 'parent';
const parentPlugin = plugins.find(plugin => plugin.name === parentName);
if (!parentPlugin) {
// or handle this silently if it is optional
throw new Error(`This plugin depends on the "${parentName}" plugin.`);
}
// now you can access the API methods in subsequent hooks
parentApi = parentPlugin.api;
},
transform(code, id) {
if (thereIsAReasonToDoSomething(id)) {
parentApi.doSomething(id);
}
}
};
}
There's also Custom module meta-data, however when I read the meta I always get null.

Xstate Cannot set property '_sessionid' of undefined

I'm trying to create an interpret for Xstate, and I'm trying to pass it a Machine I had created in a separate file, something like this:
import { Machine } from 'xstate';
const testMachine = Machine({
id: 'testMachine',
initial: 'start',
states: {
start: {
on: {
PUB_TOPIC: 'wait_micro_res',
},
},
wait_micro_res: {
on: {
MACHINE_DISCONNECTED: 'disconnection',
CONFIRMATION_RECEIVED: 'wait_order',
},
},
wait_order: {
on: {
DISCONNECTION_ORDER: 'end',
EXPERIMENT_ORDER: 'wait_measurement',
},
},
wait_measurement: {
on: {
EXPERIMENT_FINISHED: 'end',
MEASUREMENT_RECEIVED: 'receive_measurement',
},
},
receive_measurement: {
on: {
SEND_2_EXPERIMENT_MS: 'wait_measurement',
},
},
disconnection: {
on: {
RECONNECTION: 'wait_micro_res',
},
},
end: {
type: 'final',
},
},
});
export default {
testMachine,
};
I'm trying to create it this way:
import { interpret } from 'xstate/lib/interpreter';
import testMachine from '../stateMachine/index';
const machineService = interpret(testMachine)
.onTransition((state) => {
console.log(state.value);
})
.start();
However I'm getting this error:
TypeError: Cannot set property '_sessionid' of undefined
When I try to create the machine in the same file of the interpreter all runs fine. I tried to log the machine and it seems to be imported correctly, but I don't know if there's an additional mistake I'm not aware about
There seems to be a problem with your export. You are exporting { testMachine } as the default export instead of testMachine.
You should use:
export default testMachine;
Then when you import testMachine from '../stateMachine/index'; you will get the desired object.
For now you are importing an object with a property testMachine that contains you machine.
If you want to keep that export, use:
const machineService = interpret(testMachine.testMachine)

Importing Stripe.js as an ES Module into Vue

I'm trying follow the directions from the stripe elements docs and install the ES module into my Vue payment component.
Note, currently the Stripe websites ES module installation tab is down. Here's a substitute.
I ran:
npm install #stripe/stripe-js
Usage
import {loadStripe} from '#stripe/stripe-js';
const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
When I change my code to reflect the installation of the module I get this error:
30:17 error Parsing error: Can not use keyword 'await' outside an async function
import {loadStripe} from '#stripe/stripe-js';
let stripe = await loadStripe(`pk_test_mypin`)
elements = stripe.elements()
card = undefined;
export default {
mounted: function () {
card = elements.create('card', {
});
card.mount(this.$refs.card);
},
data () {
return {
cardHolderName: '',
stripeErrorMessage: null,
serverErrorMessage: null,
}
},
computed: {
},
methods: {
processPayment(){
let self = this;
stripe.createPaymentMethod(
'card', card, {
billing_details: { name: this.cardHolderName }
}).then(function(result) {
if(self.subscribitionCheckout){
self.submitPaymentForm(result.paymentMethod);
} else if (self.changePaymentMethod){
self.changePaymentMethod(result.paymentMethod)
}
if (result.error) {
self.stripeErrorMessage = result.error.message;
self.hasCardErrors = true;
self.$forceUpdate(); // Forcing the DOM to update so the Stripe Element can update.
return;
}
});
},
},
}
Before I had this
let stripe = Stripe(`pk_test_mypin`),
elements = stripe.elements(),
card = undefined;
Also, I based my code on this tutorial
First, put the expected top level vars in data:
stripe: {}, // or whatever data type
elements: {}, // or whatever data type
card: {}, // or whatever data type
Second, make a created lifecycle hook and load the content there:
created()
{
loadStripe(`pk_test_TYooMQauvdEDq54NiTphI7jx`).
then ( (result) =>
{
this.elements = result.elements
// do stuff with card if you have too...
},
},

Cannot set property 'functionName' of undefined

I am learning MEVN by watching this video https://youtu.be/H6hM_5ilhqw?t=38m28s
And I imitated to add a function to const User like below:
module.exports = (sequelize, Datatypes) =>{
const User = sequelize.define('User', {
email:{
type:Datatypes.STRING,
unique: true
},
password:Datatypes.STRING
}, {
hooks:{
beforeCreate: hashPassword,
beforeUpdate: hashPassword,
beforeSave: hashPassword
}
})
User.prototype.comparePassword = function(password) {
return bcrypt.compareAsync(password, this.password)
}
return User
}
But it always shows that TypeError: Cannot set property 'comparePassword' of undefined
(The tutorial video has no problem with it.)
I have tried to use "User.____proto____.comparePassword", and it was compiled successfully but cannot pass the function to its instance.
Hope someone can help me out, thanks!
You are using an older version of sequelize that doesn't yet support extending instances by using prototypes.
According to their documentation the older way would be to provide instanceMethods
const Model = sequelize.define('Model', {
...
}, {
classMethods: {
associate: function (model) {...}
},
instanceMethods: {
someMethod: function () { ...}
}
});
The 4.X works like you tried to make it to work.

Parenting this in Javascript

I'm trying to make the following code works without any luck, and I can't see a clear solution on how to do it.
export default {
model: null,
set: function (data) {
this.model = data
},
account: {
update: function (data) {
this.model.account = data
}
}
}
My issue here is that account.update fails because this.model does not exists. I suspect that the sub object gets a new this, hence my issue, but I don't know how to fix it.
I tried the alternative here :
export default (function () {
let model = null
function set (data) {
this.model = data // I also tried without the `this.` but without any luck too
},
function updateAccount(data) {
this.model.account = data
}
return {
'model': model,
'set': set,
'account': {
'update': updateAccount
}
}
})()
But apparently the same rule applies.
Maybe it's worth noting that I'm using Babel to compile ES6 down to ES5 javascript.
It fails because this refers (in this case) to the window object. Reference the object itself like this:
let myModel = {
model: null,
set: function (data) {
myModel.model = data // reference myModel instead of this
},
account: {
update: function (data) {
myModel.model.account = data // reference myModel instead of this
}
}
}
I would take an approach similar to your alternative solution. There is however no need to wrap your code in an IIFE, ES2015 modules are self-contained; you don't need an IIFE for encapsulation.
let model = null,
set = (data) => {
model = data;
},
updateAccount = (data) => {
if (!model) {
throw('model not set');
}
model.account = data;
};
export default {
model,
set,
account: {
update: updateAccount
}
};
Since you are already using Babel, I also used arrow functions and the new shorthand properties to make the code a little shorter/readable.

Categories

Resources