_.remove($scope.posts, post);
I', using _.remove to remove items from an array using lodash. But how do I add objects again? So what is the opposite of _.remove.
_.remove removes an item from an array, now since you want an opposite of the remove which can be push, there is no _.push available. So, i think it's better to use native push function.
here are few things you can consider:
var posts = [{a:1},{b:3},{f:3}];
var post = {a:1};
_.remove(posts, post); // posts = [{b:3},{f:3}]
to add object at 0 index
posts.unshift(post);//posts = [{a:1},{b:3},{f:3}]
to add object at last index
posts.push(post);//posts = [{b:3},{f:3},{a:1}]
to insert object at an index
posts.splice(1, 0, {g:8}); // posts = [{a:1},{g:8},{b:3},{f:3}]
and you can use _.mixin of course.
_.mixin({
push: function(arr,obj){
return arr.push(obj);
}
});
and you can use it like
_.push(posts,post);
JsFiddle for mixin example
Please try _.fill, fills elements of array with value from start up to
_.fill(array, value, [start=0], [end=array.length])
_.fill([4, 6, 8, 10], '*', 1, 3);
// → [4, '*', '*', 10]
Related
I make database with SQLite in Kotlin, and then when i deleted the first data and then i deleted the last data the problem show up.
I've been trying to make id: Int = 0, but still not work
fun deleteCaption(caption: Caption){
val db = this.writableDatabase
// Delete Caption by ID
db.delete(
TABLE_CAPTION,"$COLUMN_CAPTION_ID = ?",
arrayOf(caption.id.toString())
)
db.close()
}
I expect when i deleted the first data and then i deleted the last data it's work but the actual that's no work
IndexOutOfBound means that you are trying to use an element that is too 'far' in the array.
For example, if you have an array of size 3, the possible index are : 0, 1, 2.
So you can't get array[3].
Are you sure your array is not empty ?
Are you removing entries of your array inside a forEach loop on your array ?
I am in middle of setting up redux for managing state for all my api data. I have infinite flatlist that grow with query with offset and limit i pass to api param.
Now issue remain — I am able to get first set of data but never combine data of all api calls. I am sure i am doing something silly out there.
I am stuck badly here that investing day and night here. Any help will greatly appreciated here.
Reducer:
import { RECEIVED_NEWS } from './actions';
export const news = (state = [], action) => {
//console.log('action data is '+JSON.stringify(action));
switch (action.type) {
case RECEIVED_NEWS:
return [...state, action.apidata];
default:
return state;
}
};
Action:
export const RECEIVED_NEWS = 'RECEIVED_NEWS';
export const addNews = apidata => ({
type: RECEIVED_NEWS,
apidata
});
Sample api data : https://codebeautify.org/online-json-editor/cb73c978 or https://pastebin.com/rS8Aj4ex
Object dir that i print with console http://navgujaratsamay.co.in/wp-content/uploads/2019/02/Screenshot-2019-02-01-at-5.09.41-PM.png
I am expecting merging all all api calls and i am successfully calling store but every time getting only last call data.
You need to do:
return [...state, ...action.apidata]
because action.apidata is a array too, you need to spread it too otherwise it will get nested. If apidata was not an array just an object, then no need to spread it.
eg:
> let arr1 = [1, 2, 3, 4, 5]
> let arr2 = [6, 7, 8, 9, 0]
> [...arr1, arr2] // wrong
< [1, 2, 3, 4, 5, [6, 7, 8, 9, 0]] // gives a nested array
> [...arr1, ...arr2] // correct
< [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] // merges properly
> let num = 10
> [...arr1, num] // no spreading required when it's not an array
< [1, 2, 3, 4, 5, 10] // merges properly
I'm writing tests for Vue.js and I'm trying to write the test to ensure that when some props are changed for pagination, the resulting values within the component are updated properly.
So when I console.log the component, I see the correctly updated values, but then when I try to literally grab that attribute it gives me the old and outdated value. Look at rangeList in the following screenshot to see what I mean:
Here is my code so that you see how what is generating this output.
pagComp.$refs.component.limit = 10;
pagComp.$refs.component.pages = 145;
console.log(pagComp.$refs.component);
console.log('RangList: ' + pagComp.$refs.component.rangeList.length);
Here is the code that modifies rangeList:
createListOfRanges() {
let range = [];
for(let i = 0; i < this.pages; i++) {
range.push(i);
}
this.rangeList = [];
while(range.length > 0) {
this.rangeList.push(range.splice(0, this.rangeLength));
}
this.correctLastRange();
},
Finally, there are two places this function is called: when the component is being created, and when the pages attribute changes. Here is the watcher:
watch: {
pages(val) {
this.createListOfRanges();
}
},
I see some issues with this part of your code:
while(range.length > 0) {
this.rangeList.push(range.splice(0, this.rangeLength));
}
range.splice(..) returns an array, which is getting pushed into this.rangeList
Forget about that for a minute. Look at the following example:
x = [1, 2, 3, 4]
x.splice(0, 2) // result: [1, 2]
As you can see above, splice returns an array, not an element. Now, in the same example above:
x = [1, 2, 3, 4]
y = [10, 11]
y.push(x.splice(0, 2))
Check the value of y. It will be [10, 11, [1, 2] ]. It is an array within another array. It does not look very meaningful here. You can do the above x and y experiments directly in your developer console.
In your case, your x happens to be the local range array within createListOfRanges method, and your y is this.rangeList that belongs to your Vue component.
Can you check your app logic at around that area, and see if that is really what you want to do?
For debugging Vue.js apps, you also need Vue devtools: https://github.com/vuejs/vue-devtools - it is much better than console.log()
While #Mani is right on the line of code giving you issues is your push to rangeList.
createListOfRanges() {
let range = [];
for(let i = 0; i < this.pages; i++) {
range.push(i);
}
this.rangeList = [];
while(range.length > 0) {
this.rangeList.push(range.splice(0, this.rangeLength));
}
this.correctLastRange();
},
pushing the result of the splice just makes a single element with all the elements of range in it.
try changing it to
this.rangeList.push(range.shift());
Though your function could be simplified by pushing the for(let i = 0; i < this.pages; i++) { i value directly to rangeList unless that's a simplification.
This JSFiddle shows what I'm talking about.
I appreciate the answers above, however they aren't what the issue was.
The problem was with Vue's lifecycle. I'm not 100% sure why, but when the page and limit variables are changed it takes another moment for the page watcher (shown above) to get executed and update the component. So thus it wouldn't show up in my tests. So what I did was use nextTick like so, which fixed the problem.
pagVue.limit = 10; // limit and pages change together every time automatically
pagVue.pages = 145;
Vue.nextTick(() => {
expect(pagination.rangeList.length).toBe(25);
})
So lets say I had a chained sequence like the following:
let amount = _
.chain(selectedItemsArray)
.map(item => _.find(availableItems, {id: item.id})
//how can I determine that ALL items were found right here?
.filter('price_money')
...
Note the comment in the code above. It could be possible that the selectedItemsArray is out of date, so some selected items might not be in availableItems. So, my initial thought was to use a .tap or .thru (probably tap) to do something like _.every(selectedItems, _.isObject) or something similar to catch the error state where not all items are found and throw an error if not all items were found. This feels odd though...any better ways of handling this type of error checking mid sequence?
Something like this does work (at least I can throw an error), but seems like I'm using tap for something it's not intended for:
.tap(items => {
if (!_.every(items, _.isObject)) throw new Error('Some selected items are no longer available');
})
You can use another _.filter to check if the element is not an object, and also handle the offending value. You can use || to execute fallback code. See this question.
If you want your code to crash and burn on the first failure, use a function that throws an error instead of using console.error.
var available = [
{ id: 1, amount: 2.00 },
{ id: 2, amount: 4.00 }
];
var selected = [1, 2, 3];
var amount = _(selected)
.map(item => _.find(available, {id:item}) || item)
.filter(item => _.isObject(item) || console.error("Item not available:", item))
.sumBy('amount');
console.log("Amount:", amount.toFixed(2));
<script src="https://cdn.jsdelivr.net/lodash/4.15.0/lodash.min.js"></script>
I'm confused by how Lua properties are working in some of the code I'm trying to maintain. I've spent a good amount of time in the Lua documentation before this. So...
There is a function in one of those Lua tables, like this (we'll call this the 'nested tables' example):
function addItem(item)
index = itemTable.getIndex(item.position[1], item.position[2])
itemTable.items[index] = item
end;
a = Xpl3dSwitch { position = { 27, 0, 1, 1} }
itemTable.addItem(a) --doesn't seem to 'register' the position property
whereas
a = Xpl3dSwitch { }
a.position[0] = 27
a.position[1] = 0
itemTable.addItem(a) --this 'registers' the position properties
...etc, seems to work. Why are the position tables not sticking in the 'nested table' example?
Also, regarding 'a = Xpl3dSwitch { }' - is it an object constructor? It's not clear from the Lua 'documentation' what this is.
Look inside the table a and compare them. That should point you in the direction where the error happens.
to look inside a use something like:
function getTableContent(tab, str)
str = str or "table"
for i, v in pairs(tab) do
if type(v) == "table" and v ~= _G then
str = str.."->"..tostring(i)
getTableContent(v, str)
else
print(str.." Index: "..tostring(i).." Value: "..tostring(v))
end
end
end
getTableContent(a)
io.read()
Once you know how the working and the not working one are structured you should be able to make the adjustments needed.
Edit:
Also you could use:
a = Xpl3dSwitch { }
a.position = {27, 0, 1, 1}