How to redirect all the route paths starting with foo to paths starting with bar - react-router

The examples below demonstrate what I want to achieve:
/foo => /bar
/foo/a => /bar/a
/foo/a/b => /bar/a/b
/foo/a/b/c => /bar/a/b/c
...
I've tried <Redirect from="/foo/(.*)" to="/bar/(.*)" />, but it didn't work when the wildcard matches two or more path segments. To be specific, /foo/a/b would become /bar/a%2F/b rather than /bar/a/b.
The only feasible way I've thought of is use a function to generate multiple Redirects like below:
function generate(fromPrefix, toPrefix, maxLevel = 5) {
return Array(maxLevel)
.fill()
.map((_, i) => {
const wildcards = Array(maxLevel - i)
.fill('(.*)')
.join('/');
const from = `${fromPrefix}/${wildcards}`;
const to = `${toPrefix}/${wildcards}`;
return <Redirect from={from} to={to} />;
});
}
Is there a better way to do this?

Use a slightly more relaxed regex.
<Redirect from="/foo*" to="/bar*" />

Related

one line ES6 change one item in Array

I have the code to change state with React
const newArray = upfiles;
newArray[i] = { ...upfiles[i], status: 'Ready' };
setUpfiles([...newArray]);
I wonder if it can be done in one line.
setUpfile(Object.values({...upfiles, [i]:{...upfiles[i], status: "Ready"}}))
This should do the job in one line.
Also
setUpfile(upfiles.map((upfile, index) => index === i ? {...upfile, status:"Ready"} : upfile))
should work

What is the correct way to toggling a filter on a json array?

I have an array of json objects, and I want to be able to show either all of them, or remove some of them by filtering them by a key value.
I achieved this by creating a new constant:
const filtered = data.filter((item) => item.highVariance === false);
And a different constant:
const showHighVar = isHighVar ? data : filtered;
And then I have a checkbox that lets me toggle the shotHighVar constant in:
input type="checkbox" onChange={() => setHighVar(!isHighVar)}/>
In order to map it later in code:
{sorted(showHighVar).slice(0, 25 * pageIndex).map((x) => (...))}
But it seems to me like there should be a better way of doing this, but I can't figure it out.
There is nothing wrong with the way you are doing it. the one thing that i would change is that instead of creating filtered variable all the time just filter the data when isHighVar is false. So your code should look something like this -
const showHighVar = isHighVar ? data : data.filter((item) => item.highVariance === false);
{sorted(showHighVar).slice(0, 25 * pageIndex).map((x) => ( .....))}
Or when you are running the map function after sorting and slicing. just add a if statement in map function and check if isHighVar is false then return null else do whatever you are doing.
eg.
{sorted(data).slice(0, 25 * pageIndex).map((x) => {
if(isHighVar===false && x.highVariance!==false){
return null;
}
....
})}

ESLINT: params.majorVersion = m[1]; => Use array destructuring.(prefer-destructuring)

I'm struggling with an Eslint error about this code :
const m = version.match(/^(\d+)\.\d+\.\d+/);
...
params.majorVersion = m[1];
I have an ESLint error : Use array destructuring.(prefer-destructuring)
I tried different things like
const [,majorVersion] = m;
params.majorVersion = majorVersion
or
const [, majorVersion] = version.match(/^(\d+)\.\d+\.\d+/);
...
params.majorVersion = majorVersion
But solution 1 is more verbose, I can't see how destructuring improves anything here. And the 2nd solution doesn't work when there's no match. I'm starting to think there's a problem with this Eslint rule for this code
Am I missing something ?

How to add legend for a bar chart with different colors in dc.js?

Below is the code snippet for a barchart with colored bars:
var Dim2 = ndx.dimension(function(d){return [d.SNo, d.something ]});
var Group2 = Dim2.group().reduceSum(function(d){ return d.someId; });
var someColors = d3.scale.ordinal().domain(["a1","a2","a3","a4","a5","a6","a7","a8"])
.range(["#2980B9","#00FFFF","#008000","#FFC300","#FF5733","#D1AEF1","#C0C0C0","#000000"]);
barChart2
.height(250)
.width(1000)
.brushOn(false)
.mouseZoomable(true)
.x(d3.scale.linear().domain([600,800]))
.elasticY(false)
.dimension(Dim2)
.group(Group2)
.keyAccessor(function(d){ return d.key[0]; })
.valueAccessor(function(d){return d.value; })
.colors(someColors)
.colorAccessor(function(d){return d.key[1]; });
How do I add a legend to this chart?
Using composite keys in crossfilter is really tricky, and I don't recommend it unless you really need it.
Crossfilter only understands scalars, so even though you can produce dimension and group keys which are arrays, and retrieve them correctly, crossfilter is going to coerce those arrays to strings, and that can cause trouble.
Here, what is happening is that Group2.all() iterates over your data in string order, so you get keys in the order
[1, "a1"], [10, "a3"], [11, "a4"], [12, "a5"], [2, "a3"], ...
Without changing the shape of your data, one way around this is to sort the data in your legendables function:
barChart2.legendables = function() {
return Group2.all().sort((a,b) => a.key[0] - b.key[0])
.map(function(kv) {
return {
chart: barChart2,
name: kv.key[1],
color: barChart2.colors()(kv.key[1]) }; }) };
An unrelated problem is that dc.js takes the X domain very literally, so even though [1,12] contains all the values, the last bar was not shown because the right side ends right at 12 and the bar is drawn between 12 and 13.
So:
.x(d3.scale.linear().domain([1,13]))
Now the legend matches the data!
Fork of your fiddle (also with dc.css).
EDIT: Of course, you want the legend items unique, too. You can define uniq like this:
function uniq(a, kf) {
var seen = [];
return a.filter(x => seen[kf(x)] ? false : (seen[kf(x)] = true));
}
Adding a step to legendables:
barChart2.legendables = function() {
var vals = uniq(Group2.all(), kv => kv.key[1]),
sorted = vals.sort((a,b) => a.key[1] > b.key[1] ? 1 : -1);
// or in X order: sorted = vals.sort((a,b) => a.key[0] - b.key[0]);
return sorted.map(function(kv) {
return {
chart: barChart2,
name: kv.key[1],
color: barChart2.colors()(kv.key[1]) }; }) };
Note that we're sorting by the string value of d.something which lands in key[1]. As shown in the comment, sorting by x order (d.SNo, key[0]) is possible too. I wouldn't recommend sorting by y since that's a reduceSum.
Result, sorted and uniq'd:
New fiddle.

Accessing ImmutableJS OrderedSet()

Playing with ImmutableJS, documentation needs work and actual working examples.
const a = [["a"],["b"],["c"]]
const b = Immutable.List(a)
const c = Immutable.OrderedSet(a)
b.first() // => "a"
b.get(1) // => "b"
c.first() // => ["a"]
c.get(1) // => undefined !uh oh!
c.toList().get(1) // => "b" !indirect!
Question: How do I print out the 2nd element of .OrderedSet c without converting it to a .List or loop over the entire list?
You can do it such as:
// using some ES6 features
let ordSet = immutable.OrderedSet([1, 2, 3])
let iterator = ordSet[Symbol.iterator] // get iterator to the collection
iterator.next() // 1
iterator.next() // 2
iterator.next() // 3
This said, let me note that even if this is not the nicest syntax, from the point of performance, it is the best as it gets: OrderedSet does not provide random access to its elements, each element simply remembers its successor and predecessor. Therefore, getting n-th element requires n hops, whether immutable.js provides some fancy helper for it or not. AFAIK, such linked-list-like implementation of OrderedSet is inevitable, if add / delete should remain fast.