Lodash chaining issue - lodash

I am having trouble getting the value of my chain. I believe it has something to do with the returns in my code.
let wrapper = _.chain($scope.meetings)
.orderBy($scope.meetings, function(o) { return new moment(o.meetingDate); }, ['asc'])
.filter($scope.meetings, function(o) { return moment(o.meetingDate).isAfter(begin) && moment(o.meetingDate).isBefore(end); })
.forEach($scope.meetings, function(o) { o.createdBy = $scope.myData[0].fullName;})
.value();
I am getting an empty array as the value

as #gruff-bunny said, solve was to remove the variable from my orderBy, filter, and forEach. In the end, my function looks like this.
$scope.meetings = _.chain($scope.meetings)
.orderBy(function(o) { return new moment(o.meetingDate); }, ['asc'])
.filter(function(o) { return moment(o.meetingDate).isAfter(begin) && moment(o.meetingDate).isBefore(end); })
.value();

Related

Vue computed property: helper function returns undefined despite being defined

I am using a computed property diameter() to return either:
- a random number (randomise: true)
- a number returned from an object within an array (randomise: false).
I do have a working implementation (see bottom of post) but would like to know why the cleaner implementation doesn't work. With randomise: false, diameter() returns undefined. Why?
vars [
{varName: diameter, varValue: 25.8},
{varName: quantity, varValue: 68}
]
computed: {
diameter() {
if (randomise) {
return math.randomInt(100, 1000) //no problems
} else {
console.log(this.populateValue('diameter')) //undefined
return this.populateValue('diameter')
}
}
}
methods: {
populateValue(variableName) {
this.vars.forEach(element => {
if (element.varName === variableName) {
console.log(element.varValue) //25.8
return element.varValue
}
})
}
}
The following implementation works but why do I have to create an arbitrary property to do so?
diameter() {
if (!this.vars || !this.passVars) {
return math.randomInt(100, 1000) / (10 ** math.randomInt(0, 3))
} else {
this.populateValue('diameter')
return this.blah
}
}
populateValue(variableName) {
this.vars.forEach(element => {
if (element.varName === variableName) {
this.blah = element.varValue
}
})
}
The problem is that return element.varValue is returning from the forEach, not populateValue.
There are various ways to write this. e.g.
for (const element of this.vars) {
if (element.varName === variableName) {
return element.varValue
}
}
By using a for/of loop there is no inner function so the return returns from the function you're expecting.
Alternatives include:
let value = null
this.vars.forEach(element =>
if (element.varName === variableName) {
value = element.varValue
}
})
return value
or:
const match = this.vars.find(element =>
return element.varName === variableName
})
if (match) {
return match.varValue
}

Using set() for computed values correctly in Vue

I'm having an issue with setting a computed property (which is an array). I have the following computed property in my Vue component:
posts: {
get () {
if ( this.type == 'businesses' || this.type == 'business' ) {
return this.$store.getters.getAllBusinesses.map(_business => {
return _business
})
} else if ( this.type == 'shops' || this.type == 'shop' ) {
return this.$store.getters.getAllShops.map(_shop => {
return _shop
})
} else if ( this.type == 'events' || this.type == 'event' ) {
return this.$store.getters.getAllEvents.map(_event => {
return _event
})
} else {
return this.$store.getters.getAllBusinesses.map(_business => {
return _business
})
}
},
set (posts) {
console.log(posts)
this.posts = posts // Doesn't work - this causes a maximum call stack error, recursively setting itself obviously.
return posts // Doesn't work either - this.posts doesn't seem to be changing...
}
},
The console.log(posts) is exactly what I want - a filtered array of posts, see the below console log output.
My question is simply this: how do I go about updated the computed posts value?
If it is useful, I am doing the following manipulation to the posts:
let filteredPosts = []
this.posts.filter(_post => {
_post.category.forEach(category => {
if ( this.categoryFilters.includes(category.slug) ) {
filteredPosts.push(_post)
}
})
})
let uniqueFilteredPosts = [...new Set(filteredPosts)];
this.posts = uniqueFilteredPosts
This is purely to filter them. What I am console.logging is absolutely correct to what I want. So this might be a red herring.
Any pro-Vue tips would be greatly appreciated!
If you want to use a computed setter, you normally assign to whatever values underlie the computed's get function. See the example at the link.
In your case, you examine this.type and return something from the store based on it. The setter should probably examine this.type and set something in the store based on it.

ExtJS Callback Functions Example

I'm a newbie at ExtJs and I'm struggling to figure out how to use callback functions in ExtJs. The ExtJs version I'm using is 4.2.1
Basically I want to chain the execution of 2 functions:
func1: function() {
}
func2: function() {
}
so that func2() only starts executing after func1() completes.
From what I've read so far, I need to use callback function, but for the life of me I cannot get it.
Here Is my code:
filter: function (filters, value) {
if (Ext.isString(filters)) {
filters = {
property: filters,
value: value
};
}
var me = this,
decoded = me.decodeFilters(filters),
i = 0,
length = decoded.length;
for (; i < length; i++) {
me.filters.replace(decoded[i]);
}
Ext.Array.each(me.filters.items, function (filter) {
Ext.Object.each(me.tree.nodeHash, function (key, node) {
if (filter.filterFn) {
if (!filter.filterFn(node)) node.remove();
} else {
if (node.data[filter.property] != filter.value) node.remove();
}
});
});
me.hasFilter = true;
console.log(me);
},
clearFilter: function() {
var me = this;
me.filters.clear();
me.hasFilter = false;
me.load();
},
isFiltered: function() {
return this.hasFilter;
},
filterNavAdminSTByUserName: function (nameValue) {
this.clearFilter();
this.filter([{
property: 'userName',
value: nameValue
}]);
}
My problem is that this.filter() gets executed before this.clearFilter(); How do I force this.filter() to execute only after this.clearFilter() completes?
Thanks in advance!
After some soul searching I've finally figured out how callback functions work.
So here is the solution:
clearAndFilter: function (nameValue) {
var me = this;
me.filters.clear();
me.hasFilter = false;
me.load({
scope: me,
callback: function () {
// filter the store
me.filter('userName', nameValue);
}
});
},
filterNavAdminSTByUserName: function (nameValue) {
this.clearAndFilter(nameValue);
}
Feels good to answer to my first ever post here!

Howto remove a entry from the tree in a Less visitor plugin

I tried the following:
module.exports = function(less) {
function RemoveProperty() {
this._visitor = new less.visitors.Visitor(this);
};
RemoveProperty.prototype = {
isReplacing: true,
isPreEvalVisitor: true,
run: function (root) {
return this._visitor.visit(root);
},
visitRule: function (ruleNode, visitArgs) {
if(ruleNode.name[0].value != '-some-aribitrary-property')
{
return ruleNode;
}
else
{
return new less.tree.Rule([], [], 0,"");
}
}
};
return RemoveProperty;
};
return new less.tree.Rule([], [], 0,""); still result in a empty output like : ; also return nothing will give me an error: TypeError: Cannot read property 'splice' of undefined.
It can.. but its not ideal from a performance perspective.. return an empty array
visitRule: function (ruleNode, visitArgs) {
if (ruleNode.variable) {
return [];
}
return ruleNode;
},
If you check out the toCSS visitor it does this alot.
But I think it should allow undefined too.. Will look at adding that soon.

using contains instead of stringStartsWith knockout js

I have the folliwng on my model:
self.filteredItems = ko.computed(function () {
var filter = this.filter().toLowerCase();
if (!filter) {
return this.sites();
} else {
return ko.utils.arrayFilter(this.sites(), function (item) {
return ko.utils.stringStartsWith(item.Name().toLowerCase(), filter);
});
}
}, self);
I use it for a search on my page but rather than stringStartsWith I'd like some sort of .contains instead so I get results where my searchterm is contained anywhere in the string rather than just at the beginning.
I imagine this must be a pretty common request but couldnt find anything obvious.
Any suggestion?
You can use simply the string.indexOf method to check for "string contains":
self.filteredItems = ko.computed(function () {
var filter = this.filter().toLowerCase();
if (!filter) {
return this.sites();
} else {
return ko.utils.arrayFilter(this.sites(), function (item) {
return item.Name().toLowerCase().indexOf(filter) !== -1;
});
}
}, self);