React - Re-arrange/swap elements in an array map - javascript

I'm creating a simple list that I'd like to be able to "sort / rearrange" via up/down arrows, like so : https://codesandbox.io/s/stupefied-kilby-thcd6?file=/src/App.js
I am currently using array.splice to return my "from" item, and then once again using splice to insert the "from" item at its desired location
I can currently see this occurring "properly" in the console.logs, however I am unable to re-render my map to reflect the index positions, I have provided my map with a proper key (the ID's), and so I believe I've covered my base there.
When calling setState with my "sorted" array, I can see no visual change, and I'm looking for suggestions, thanks!

Just use the spread operator when setting options as shown below:
setOptions([...newOptions]);

Related

ReactJS - Duplicated objects in state array remain linked

I've reproduced the issue in the following codesandbox:
https://codesandbox.io/s/unruffled-danilo-mbb0e?file=/src/App.js
I have a state array of objects [{name:"Tom"},{name:"Dick"},{name:"Harry"}].
I want to be able to duplicate the object present at a specific index in the array. I've provided a button "Duplicate" to do so in the sandbox.
Follow the following steps in the sandbox to recreate the issue:
Click Duplicate under "Dick" to duplicate the Dick object in the state array
Now click "change" under one of the two Dicks. Notice that my code only changes one "Dick" object in the state array, but the other duplicate one automatically gets changed.
I want to avoid this. I don't want the two Dick objects to remain linked forever. How do I do this?
Your'e shallow copying the array. You need to deep copy.
Replace let copy = cur.slice(); with let copy = cur.map(item => {return {...item}}); and your code should work. basically we need to destructure the inner object to get a new copy of the every object in the array. You can read about this here Object Immutability in JS

Using react-spring useSprings with dynamic items array

I am attempting to use react-spring's useSprings to enable users to reorder the items in a formik FieldArray. The useSprings Draggable List demo (found here) uses useRef to manage the order of items. FieldArray comes with a number of array helper functions for inserting, removing, and moving items.
The issues that I'm having are:
1) Re-ordering existing items using formik's move array helper method successfully changes the array order, but requires an additional click to render the correct order
2) Adding or removing array items using array helper methods produces unexpected results. Mutating the length of the ref doesn't change the length of order.current inside of useGesture
I've also tried using useState instead of useRef and updating the state with useEffect when props change.
Here is a code sandbox I made: https://codesandbox.io/s/usesprings-with-fieldarray-56bex
In the bind function, commenting out order.current = newOrder; and uncommenting // arrayHelpers.move(currIndex, currRow); shows issue #1 that I mentioned above.
I would like to be able to use formik's move, insert, and remove helper functions with react-spring to seamlessly re-order, add, and delete items within a FieldArray.
maybe you can try setting the new order.current after adding the new element
onClick={() =>{
arrayHelpers.insert(items.length, {
name: `Item ${items.length + 1}`
})
order.current = [...order.current, order.current.length];
}
}
this will add the new item at the end of the list.
I encountered at least your #1 issue.
Note that the the setSprings function doesn't re-render anything on its own, and the useSprings is missing a dependencies array to auto-update.
react-springs#9.0.0.beta-23 has a dependencies array, and together with the useSpringsFixed wrapper in the sandbox that is linked here it should force-rerender on changed props.
Hope that helps your issue too.

Heatmap DC.js - how to filter multiple items manually

I'm working on a heatmap chart using dc.js. During the page loads, i want to manually filter the heatmap.
For example, if it filter using this heatmap.filter("30,0"); it works when the page loads. but when i try to filter multiple values using the .filter() function, it didnt work.
I tried doing this just for testing.
var test = [];
test.push("30,0");
test.push("40,2");
heatmapChart.filter(test);
Though it works if its only one item, but if i add another array item, the chart breaks. Is there a specific way to filter multiple items manually?
Yes, but there are a few layers of weird between here and there.
First, the actual filter items are constructed using dc.filters.TwoDimensionalFilter - I think your comma separated strings are only working by accident.
Second, the chart has already overridden .filter() so if you want to get at the base version which can handle multiple items, you need to call chart._filter() instead.
Finally, and weirdest of all, the syntax for filtering on multiple items is to supply an array containing a single array of filter items.
Putting these all together,
var ff = [dc.filters.TwoDimensionalFilter([0,2008]),
dc.filters.TwoDimensionalFilter([3,1994]),
dc.filters.TwoDimensionalFilter([9,2000])];
heatmapChart._filter([ff]);
works with the heatmap filtering example. Note the array of array of filters!

angular filter alphabetically but add new to top

I have a list of objects coming to my page and I'm using orderBy:
orderBy:"name":false
// the object also has an id:number
this is great for the original list, but when I add new items, I want the items to go above the older items (until the page is refreshed). Is there a way to tell angular to automatically take care of this?
Angular does not have a built in parameter to place new items at the top or bottom, but you could easily build the functionality in yourself. Upon creating an item, add a property like item.isNew Finally change your sort to a multisort:
orderBy:["isNew","name"]
This should have the desired result, and (combining with ng-class or css selectors) allows you to style the new item differently if you wish.
Edit:
Here is an example jsfiddle. I forgot to mention that the new items will be at the top, but all new items will be sorted by name. If you just want them just "pushed onto the stack" with no additional sorting change your "isNew" variable from a Boolean to an decrementing Integer (example here).

Ember filterBy - using more than one value to filter

How can I use more than one value to filter a list using the filterBy function?
My scenario is - I have a list of consoles which I want to filter based on the console_id.
Unfortunately, I don't have control over the JSON so each consoles has a different ID. I would like to loop through the Console IDs within the nested assignedConsole JSON and then filter through the root assignedConsole JSON.
I can get the console ID of the first object and place it into the filter but I don't know how I can use two values
I have created a emberjs bin to demonstrate my problem: http://emberjs.jsbin.com/kojute/2/
After some clarification from my previous answer, I realized you want to filter by console instead of filtering the assignedConsole values. My suggestion is to add a selectedConsole property on the controller, and display the array of assignedConsoles for the selected console.
Working JSBin: http://jsbin.com/nuroyuvuta/9
EDIT: See my other answer for the working solution!
I would suggest creating a computed property on your model or your controller that flattens that nested structure for you:
allConsoles: function() {
return this.get('consoles')
.mapProperty('assignedConsoles').reduce(function(a, b) {
return a.concat(b);
})
.uniq();
}.property('consoles.#each')
This will first get all of the items from the consoles property, then map all of their assignedConsoles to an intermediate value, which is then reduced by adding all the assignedConsoles together. The final uniq() call just removes any duplicates found in the array.

Categories

Resources