Vuex Mutation: Cannot read properties of undefined (reading 'Id') - vue.js

I seem to be running into an odd problem. I have a mutation that removes an object from one array in my state, and then disable the same object in a different array. It works fine most of the time, I add them and remove them with my buttons. But after I've done it 4 - 5 times (a random amount of times it seems), the next time I click it I get the error:
500
Cannot read properties of undefined (reading 'Id')
Console:
TypeError: Cannot read properties of undefined (reading 'Id')
at eval (mutations.js?014a:69:1)
at Array.find (<anonymous>)
at Store.BOOKING_REMOVE_SESSION (mutations.js?014a:68:1)
at wrappedMutationHandler (vuex.esm.js?2f62:844:1)
at commitIterator (vuex.esm.js?2f62:466:1)
at Array.forEach (<anonymous>)
at eval (vuex.esm.js?2f62:465:1)
at Store._withCommit (vuex.esm.js?2f62:624:1)
at Store.commit (vuex.esm.js?2f62:464:1)
at Store.boundCommit [as commit] (vuex.esm.js?2f62:409:1)
My mutation:
BOOKING_REMOVE_SESSION: (state, sessionData) => {
state.performBooking.sessions.find((o,i) => {
if(o.Id === sessionData.Id){
state.performBooking.sessions.splice(i, 1)
}
})
let sessionIndex = state.currentShow.sessions.findIndex(x => x.Id === sessionData.Id)
state.currentShow.sessions[sessionIndex].activated = false;
}
It seems to do exactly what I want except when it errors. I think it has something to do with when there are a few things in the state.performBooking array. I reckon the problem is with o.Id === sessionData.Id not being able to find a matching ID for some reason.
It's used in conjunction with a button that calls a method:
removeSession(sessionData) {
this.$store.commit('BOOKING_REMOVE_SESSION', sessionData)
}
A sample piece of data would be:
{
attributes: [Object],
Id: 'a1g960010000sJSAAY',
Capacity__c: 5,
Performance__c: 'a1f960001000HMZAA2',
Name: 'Test Performance #041',
Time__c: '2021-11-19T15:00:00.000+0000',
Version__c: 'General'
},
Any help would be greatly appreciated cheers.

I answered it myself by making it less verbose.
Since I'm just looking for the Id I did it in a variable.
OLD:
state.performBooking.sessions.find((o,i) => {
if(o.Id === sessionData.Id){
state.performBooking.sessions.splice(i, 1)
}
})
NEW:
let localSessionIndex = state.performBooking.sessions.findIndex(o => o.Id === sessionData.Id)
state.performBooking.sessions.splice(localSessionIndex, 1)

Related

Vue.js Nuxt - cannot access Array (value evaluated upon first expanding error)

I have the following function which gives me an array called URLs
const storageRef = this.$fire.storage.ref().child(fileName)
try {
const snapshot = storageRef.put(element).then((snapshot) => {
snapshot.ref.getDownloadURL().then((url) => {
urls.push(url)
})
})
console.log('File uploaded.')
} catch (e) {
console.log(e.message)
}
});
console.log(urls)
console.log("about to run enter time with imageurls length " + urls.length)
When I run console.log(URLs) initially I do see the array like the following
[]
0: "testvalue"
length: 1
__proto__: Array(0)
However, there is a small information icon stating
This value was evaluated upon first expanding. The value may have changed since.
Because of this, when I try to get the length of URLs, I get zero, meaning the value is being updated.
Does anyone know what's happening? I am using Vue.JS/Nuxt.

TypeError: Cannot read property 'replace' of undefined in the context of VueJS

I am filtering some of the characters from the string. I went across few questions which has a same problem ie error in the console, but could not find any good answers.
Here is my string:
response_out1|response_out2|response_out3
Here is the method that i have used:
<vs-select v-model="change">
<vs-select-item :key="index" v-bind="item" v-for="(item,index) in
userFriendly(out.changes)" />
</vs-select>
...
methods: {
userFriendly (str){
return str.replace(/_/g, ' ').split('|').map(value => ({text: value, value }))
}
Here is the output that i am getting in the vs-select:
response out1
response out2
response out3
The error that i am getting in my console:
Here i want to know why i am getting this error and i wanna know how to rectify it and the output that i am expecting is: Response Out1, here how to capitalize first character of each word in the same method.
you're using a method directly in the template which causes multiple calls whenever your data changes,
you can use computed property to avoid such a scenario, not sure about how you are accessing out.changes
this might help you to solve your error and capitalize your text,
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
},
sentenceCase (sentence) {
return sentence.split(' ').map(s => this.capitalize(s)).join(' '));
},
userFriendly (str) {
if (!str) return;
return str.replace(/_/g, ' ').split('|').map(value => ({text: this.sentenceCase(value), value }))
},

expect is throwing an "AssertionError: expected { Object (browser_, then, ...) } to equal true"

I have an error with the expect on my tests
I'm getting this error
[08:41:37] E/launcher - expected { Object (browser_, then, ...) } to equal true
[08:41:37] E/launcher - AssertionError: expected { Object (browser_, then, ...) } to equal true
at role.element.getText.then (/Users/jburquez/akamai/ConsoleUI/tests/e2e/console_bdd/steps/manage_agents_steps.js:114:109)
at elementArrayFinder_.then (/Users/jburquez/akamai/ConsoleUI/node_modules/protractor/built/element.js:804:32)
at ManagedPromise.invokeCallback_ (/Users/jburquez/akamai/ConsoleUI/node_modules/selenium-webdriver/lib/promise.js:1376:14)
at TaskQueue.execute_ (/Users/jburquez/akamai/ConsoleUI/node_modules/selenium-webdriver/lib/promise.js:3084:14)
at TaskQueue.executeNext_ (/Users/jburquez/akamai/ConsoleUI/node_modules/selenium-webdriver/lib/promise.js:3067:27)
at asyncRun (/Users/jburquez/akamai/ConsoleUI/node_modules/selenium-webdriver/lib/promise.js:2927:27)
at /Users/jburquez/akamai/ConsoleUI/node_modules/selenium-webdriver/lib/promise.js:668:7
at process._tickCallback (internal/process/next_tick.js:68:7)
[08:41:37] E/launcher - Process exited with error code 199
[08:41:37] '<anonymous>' errored after 1.42 min
[08:41:37] Error in plugin "gulp-protractor"
Message:
protractor exited with code 199
Details:
domain: [object Object]
domainThrown: true
And this is my code on the step
Then('Validate role {editrole} is selected', { timeout:30 * 1000 }, (editrole) => {
var agentRoles = element.all(by.repeater('ctrl.roles'));
agentRoles.each((role) => {
return role.element(by.xpath(".//div[#class='md-whiteframe-1dp outset inset']/md-checkbox")).getText()
.then((roleSelected) => {
if (editrole === roleSelected) {
expect(element(".//div[#class='md-whiteframe-1dp outset inset']/md-checkbox").isSelected()).to.be.equal(true);
}
});
});
});
What i'm trying to do is verify if an element is checked so reading another suggestions I saw that .isSelected() is the best option for this, but i'm not sure why is throwing this error.
Hope you can help me!!
It looks like you are trying to compare an Object to Boolean.
You have to resolve a promise to do that or else use 'eventually' if you are using 'chai' as your assert library. Sample below:
expect(element(".//div[#class='md-whiteframe-1dp outset inset']/md-checkbox").isSelected()).to.eventually.equal(true);
Or
element(".//div[#class='md-whiteframe-1dp outset inset']/md-checkbox").isSelected().then(function (select) {
expect(select).to.be.true;
});
It takes a little while to figure out the right way of using expect with promises.
I suggest to look at async/await syntax. And also you can try to use browser.wait(ExpectedConditions.elementToBeSelected) here
Then('Validate role {editrole} is selected', { timeout:30 * 1000 }, async (editrole) => {
const agentRoles = element.all(by.repeater('ctrl.roles'))
expect(await agentRoles.count()).not.to.be(0)
await browser.wait(ExpectedConditions.elementToBeSelected(
element(by.cssContainingText('div.md-whiteframe-1dp.outset.inset md-checkbox', editrole))
), 10000, `Expected ${editrole} to be selected`);
});

Accessing elements in JSON for nodejs

first off I am very new to node/JSON, so please take that into consideration when reading through.
The purpose of this code is to take data from a SQL Server database, and be able to access the elements that it pulls. For example, it will pull several thousand parentacccount ID's, and I just want to access one of those.
I've browsed forums for almost the entire day trying to access JSON elements from my nodejs function, and I every time I try and access one of these elements I am hit with an "undefined" error. As a last resort I am here.
I have checked a few times to see recordset has been parsed, and it appears that it is being parsed.
Below is my code, and a very small example of the JSON code is towards the end.
I have commented where I am getting my error.
function getEmp() {
var conn = new sql.ConnectionPool(dbConfig);
var req = new sql.Request(conn);
conn.connect(function (err) {
if (err) {
console.log(err);
return;
}
req.query("SELECT * FROM parentaccount Where accountname like 'Titan%' FOR JSON PATH", function (err, recordset) {
if (err) {
console.log(err);
}
else {
const Test1 = recordset[0].ParentAccountId; //error here
console.log(Test1);
}
conn.close();
})
})
}
getEmp();
//EXAMPLE JSON
{ recordsets: [ [ [Object] ] ],
recordset:
[ { 'JSON_F52E2B61-18A1-11d1-B105-00805F49916B':
'[{"ParentAccountId":4241411,"AccountName":"Titan"} ],
output: {},
rowsAffected: [ 3 ] }
ERROR:
TypeError: Cannot read property 'ParentAccountId' of undefined
at C:\Users\za47387\Desktop\Excel Export Code\test2.js:31:48
at _query (C:\Users\za47387\node_modules\mssql\lib\base.js:1347:9)
at Request.tds.Request.err [as userCallback] (C:\Users\za47387\node_modules\mssql\lib\tedious.js:671:15)
at Request.callback (C:\Users\za47387\node_modules\tedious\lib\request.js:37:27)
at Connection.endOfMessageMarkerReceived (C:\Users\za47387\node_modules\tedious\lib\connection.js:2104:20)
at Connection.dispatchEvent (C:\Users\za47387\node_modules\tedious\lib\connection.js:1084:36)
at Parser.tokenStreamParser.on (C:\Users\za47387\node_modules\tedious\lib\connection.js:914:14)
at Parser.emit (events.js:189:13)
at Parser.parser.on.token (C:\Users\za47387\node_modules\tedious\lib\token\token-stream-parser.js:27:14)
at Parser.emit (events.js:189:13)
From what the sample you have shared,
recordset[0] is undefined, meaning either two options :
a) the result for the query fetched no rows.
b) the result of the query is in a different format than expected.
though i suspect a), its good to console the output. kindly run the below code before you try accessing ParentAccountId.
console.log('output : ', JSON.stringify(recordset, null, 4));
also i would refactor the code to be :
const Test1 = (Array.isArray(recordset) &&
recordset.length) ? recordset[0].ParentAccountId : null;
so that the error won't make the nodejs process go down.

Why does Ramda work in this example where native Array.map or Lodash do not?

In the process of writing an example for this SO question, this question came up:
Why does the native Array.map throw an error when used like this:
[tmp1, tmp2].map(fs.createReadStream)
.forEach(stream => stream.pipe(jsonStream));
fs.js:1664
throw new TypeError('"options" argument must be a string or an object');
^
TypeError: "options" argument must be a string or an object
at new ReadStream (fs.js:1664:11)
at fs.createReadStream (fs.js:1649:10)
at Array.map (native)
Similarly with lodash… but it works fine with ramda.
// Same error:
_.map([tmp1, tmp2], fs.createReadStream)
.forEach(stream => stream.pipe(jsonStream));
// Works fine:
R.map(fs.createReadStream, [tmp1, tmp2])
.forEach(stream => stream.pipe(jsonStream));
Note, this is the full code from referenced question:
var fs = require('fs');
var path = require('path');
var JSONStream = require('JSONStream');
var tmp1 = path.join(__dirname, 'data', 'tmp1.json');
var tmp2 = path.join(__dirname, 'data', 'tmp2.json');
var jsonStream = JSONStream.parse();
jsonStream.on('data', function (data) {
console.log('---\nFrom which file does this data come from?');
console.log(data);
});
[tmp1, tmp2].map(p => {
return fs.createReadStream(p);
}).forEach(stream => {
stream.pipe(jsonStream);
});
The second argument of fs.createReadStream should be undefined no?
This is most likely due to Array.prototype.map and _.map passing three arguments to the provided mapping function (the value, the index and the collection), while R.map only passes the value.
In your example, fs.createReadStream is being given the array index as its second argument where it expects an options object or string instead, causing the "options" argument must be a string or an object error. If you want to use Array.prototype.map or _.map in this way, you'll need to wrap the method call in a function to prevent the extra arguments:
[tmp1, tmp2].map(p => fs.createReadStream(p))