How can I convert string into an imported alias in React? - javascript

I have got an image folder that contains images of playing cards and I imported them as follow:
import D2 from "../image/D2.png";
import H2 from "../image/H2.png";
import S2 from "../image/S2.png";
and all the way until I reach SA (Spade Ace)
I also have key value pair dictionary such as:
1: "C2",
2: "D2",
3: "H2",
4: "S2",...
I need this dictionary to both calculate the rank of the card and to generate image.
atm I can retrieve the value by evaluating the last char of the string and convert it into int (in case of K,Q etc I have a switch case for them)
My issue is I have trouble to convert the string into the alias that I imported.
I tried doing eval(4) but it didn't work.
if I modified the dictionary into
1: C2,
2: D2,
3: H2,
4: S2,...
I can easily use this as the src of my images, but I can no longer use the card-code to obtain the value of the card.
Could you please suggest a solution or a better approach for this problem.

If I follow the question properly can't you just create the dictionary in this manner? If you intend to use card codes to obtain the value / image then you could build your dictionary like so:
dict = {
C2: { image: C2, value: 1 },
D2: { image: D2, value: 2 },
...
}
c2Image = dict['C2'].image;

Related

jQuery SheepIt demo indexes are wrong using nested forms

I am using the demo here: http://www.mdelrosso.com/sheepit/index.php?lng=en_GB&sec=demo3
But if you have two of the outer forms (addresses) and two each for the inner forms (numbers) and inspect the elements you'll notice the names of the inputs still have the #index# and/or #index_phone# strings in the index names.
If you try to submit the form then, the field data is lost (since only the latest copy of that name is kept). I've tried debugging the JavaScript so I can patch it, but I'm not seeing where it's wrong. It seems like the normalizeForms function isn't handling nesting correctly.
What can I do to correct the code so the indexes perform as expected? (That is: so that an input of two addresses (A and B), each with two phone numbers (A1, A2 and B1, B2) gives me a POSTed value like:
"people" : [
0 : {
"addresses" : "A",
"phones" [ 0 : "A1", 1: "A2" ]
},
1 : {
"addresses" : "B",
"phones" [ 0 : "B1", 1: "B2" ]
}
]
(Note: I'm not looking for that exact format; I can parse any output, I just need to get all of the data from the client to the server with meaningful indexes and without conflicts.)
There appear to be some fundamental logic issues with the index 'normalization' side of this plugin when it comes to the nested inputs.
Essentially there is is a nametemplate and an idtemplate which are the element names only with %index% or %index_phones% where the index should be, and then the name and id which should be these templates only with the %index% or %index_phones% replaced with the actual element input ids.
What happens during the 'normalization' process is that a function runs over these templates (once per element per form), and depending on the form, replaces either %index% or %index_phones% with the relevant index, depending on which form is being processed.
The problem arises when the inputs are nested, as the function first replaces (for instance) %index% with let's say 0. It then updates the resulting name or id with this value, say person_addresses_0_phones_%index_phones%_phone. When it hits the nested form, it then does the same again, only with %index_phones%. The result is now person_addresses_%index%_phones_0_phone because it is still using the unmodified template attribute, rather than the already half-modified name.
To fix this properly, the logic around this whole section of the plugin really needs rebuilding, but I have slapped together a quick patch which should serve as a temporary fix.
In the main plugin file, update the normalizeFieldsForForm function to be:
function normalizeFieldsForForm(form, index)
{
form.find(formFields).each(function(){
var that = $(this)
,idTemplateAttr = getOrSetTemplate(that,"id")
,nameTemplateAttr = getOrSetTemplate(that, "name")
,idAttr = that.attr("id")
,nameAttr = that.attr("name")
,formParents = that.parents('[idtemplate]')
/* Normalize field name attributes */
var newNameAttr = nameTemplateAttr.replace(options.indexFormat, index);
/* Normalize field id attributes */
var newIdAttr = idTemplateAttr.replace(options.indexFormat, index);
$.each(formParents,function(index,element){
$element = $(element);
if($element.data('indexFormat') != options.indexFormat){
/* Normalize field name attributes */
newNameAttr = newNameAttr.replace($element.data('indexFormat'), $element.data('formIndex'))
/* Normalize field id attributes */
newIdAttr = newIdAttr.replace($element.data('indexFormat'), $element.data('formIndex'))
}
});
form.find("label[for='"+idAttr+"']").each(function(){
$(this).attr("for", newIdAttr);
});
that.attr("id", newIdAttr);
that.attr("name", newNameAttr);
});
}
And then update the addForm function. Around line 385 in an unmodified plugin file, add the line
// Index format
newForm.data('indexFormat', options.indexFormat);
above the line
// Index
newForm.data('formIndex', getIndex());
This should serve as a fix until the plugin author gets around to fixing the logic issues. This is for plugin version 1.1.1

Algorithm to turn JavaScript object into efficient query string/urls

Context: I have been building an application that creates and uses magnet links. I've been trying to find an efficient way to transfer a javascript object in the Querystring so that On the other side I can deserialize it into an object keeping the same types. with efficient i mean using as little characters as possible/transferring as much data as possible. I've found my application has a max of +-1500 characters in url.
At first I used original Querystring npm packages but these can change types on deserialize and also very inefficient on deeper objects.
eg:
var input = { age: 12, name:'piet'};
var qs = querystring.encode(input); // ?age=12&name=piet
var output querystring.decode(qs); // {age: '12', name: 'piet'
Then I've tried using json stringifying with and without base64 for Querystrings. But this left me most of the time with much bigger strings for simple objects.
var input = { age: 12, name:'piet'};
var qs = encodeURIComponent(JSON.stringify(input)); // "%7B%22age%22%3A12%2C%22name%22%3A%22piet%22%7D"
But this leaves me with rediculous long querystring because half of the characters get encoded and become 3x as long which almost doubles the length.
base64 encoding in this case is a much better solution:
var input = { age: 12, name:'piet'};
var qs = btoa(JSON.stringify(input)); // eyJhZ2UiOjEyLCJuYW1lIjoicGlldCJ9
I've been trying to Google for an efficient algorithm it but haven't really found a good solution. I've been looking into msgPack binary serialisation by then I would also have to base64 which probably ends with a longer string.
Is there a known more efficient algorithm for object to Querystring serialisation with static types? or would i have to create my own?
I've been thinking on on a simple query string algorithm that works as follows:
Query string order is imporotant, for next point:
Keys starts with . shows depth: ?obj&.property="test" = { obj : {property: "test" }}
First character in string defines its type: b=boolean, s=string,n=number, (etc if needed)
This would lead to much more efficient query string i think. but am i not building something that has already been made before?
Surely sticking the stringified object into a single URI value should work?
var test = { string: 'string', integer: 8, intarray: [1,2,3] };
encodeURIComponent(JSON.stringify(test))
// "%7B%22string%22%3A%22string%22%2C%22integer%22%3A8%2C%22intarray%22%3A%5B1%2C2%2C3%5D%7D"
JSON.parse(decodeURIComponent("%7B%22string%22%3A%22string%22%2C%22integer%22%3A8%2C%22intarray%22%3A%5B1%2C2%2C3%5D%7D")
// {string: "string", integer: 8, intarray: [1, 2, 3]}
The object parsed at the end has the same types as the object inputted at the start.
Just stick your object into a single key:
var url = 'http://example.com/query?key=' + encodeURIComponent(JSON.stringify(object));
Right? And on the server you just parse that single value into an object.

ReactJS: updating props - turning a 17 object array of 2 key:value pairs into one with 3 key:value pairs

I'm fairly new/junior to front end programming but I'm helping another to build a web UI for an application. For the most part, I've learnt enough to have a basic idea of what everything does, although I'm trying to add a feature which is a bit difficult.
Long story short, I have two ag-grids (using reactJS). The main one holds data and can be filtered, and I'm trying to make a second one that not only holds the column names from the main one but also as dynamically list the filters that were applied. This second grid is like an assistant/helper grid for the user
My understanding helped me get half way through implementing this so far (I've managed to populate the second ag-grid with all the column headers from the main grid).
The column headings data were stored and picked up from props. something similar to:
rowData : this.props.report.view.columns
if you run console.log(this.props.report.view.columns) (I'm using the console from chrome developer tools), you will see an array of 17 objects which hold column information. Structure shown below:
report: Object
|
--view: Object
|
--columns: Array(17)
|
--0: Object
| |
| -- field: "testColumn"
| headerName: "testColumn"
|
--1: Object
--2: Object
--3: Object
.
.
.
--16: Object
I'll just say this looks like an array of 17 objects, each holding two key:value pairs. What I want to do is add a third keyvalue pair
I have another prop that gives key:value pairs of only columns that have filters applied (i.e. columnName:blah , filter:blahh where the column names are stored under a different key name).
the pseudo code I plan to implement goes something like this:
For EACH element in the 17 Object array (this.props.report.view.columns)
if headername = columnName (i.e. from column from filter prop)
THEN
add new key:value pair headerName:filter; to that object element
ELSE
add new key:value pair headerName:''; (an empty value) to that object
What I will end up with is changing this 17 object array of 2 key:value pairs, to a 17 object array with 3 key value pairs
Is something like this possible? If so can I get some advice?
I'm a bit worried the whole plan I used is wrong. My senior colleague suggested I used a different plan using callbacks but I didn't see how that would be possible without major code changes (which is why I stuck to my intuition)
With the map method ? https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map
const data = [
{a: 7, b: 0},
{a: 4, b: 7},
{a: 9, b: 6},
{a: 1, b: 7},
];
const newData = data.map(currObj => ({...currObj, c: 0}));
console.log(newData);

Split string on [] brackets

the string is the name of some input fields. Examples:
a[b][c]
x[y][z][]
I'm trying to produce multidimensional arrays from it.
a.b.c = value
x.y.z = [value] (value is an array because of [])
anyway i have some ideas on how to do that but first I need to split the string into an array that contains all keys and subkeys.
Searching google I've come up with this
var parts = inputName.match(/[^\[\]]+/g);
it gets me [a,b,c], but on the 2nd example I get [x,y,z] instead of [x,y,z, null]
Any way I can also match [] and add it to the list as null ? I'm not that familiar with regular expressions
#AnnaK. Why can't you simply use ids and keys to send your
information? Is it a form that is dynamic in its size? Is it because
you're developing a framework that needs to be dynamic? Is it because
you're using a function multiple places? Can't you serialize it by
using the names? We can't give you suggestions because we still don't
know why you need to transfer it as an array (which would be
serialized anyway), and we still don't know what your form looks like
Because I'm trying to send the form data with Ajax. Also, before I send the data, I need to prepend a few fields that I create with javascript. I cannot serialize it, at least not with jQuery.serializeArray if that's what you meant, because if I have multiple keys like x[y][z][], only the last one will appear
You can use the following solution:
var parts = inputName.split(/[[\]]{1,2}/);
parts.length--; // the last entry is dummy, need to take it out
console.log(parts); // ["x", "y", "z", ""]
If you need the null value (because there is processing you have no control over for example) you can use this snippet to update the result (curtesy of #Ties):
parts = parts.map(function(item){ return item === '' ? null : item });
Basic idea I had was to look for a [] and than use map() to replace it with null.
("a[bb][c][]").match(/([^[\]]+|\[\])/g).map( function(val) { return val==="[]" ? null : val; });
Regex: ([^\[\]]|\[\])+
Will match:
a[b][c] // a, b, c
x[y][z][] // x, y, z
1[][2][][3][] // 1, [], 2, [], 3, []

JavaScript switch case: anyway to force the order of the elements as they are written out?

I've got results being returned to a Google Mapping application in the div sidebar. The results are names of businesses that belong to categories that the client wants returned in a certain order. And unfortunately it's not a straight alpha sort. So one category begins with F and the second one with a C and the last three are A's, for example.
So I need my switch, which works, but naturally insists on dropping the values in alpha sorted (as they are returned from the DB that way) order as that's how it encounters them. What's the best way to set this up so I can grab my preferred categories with their associated company names in the arbitrary order the client has asked for?
Thanks!
Can you iterate over the categories in the order you want them in, and find the object to which it is associated?
E.g. (pseudocode)
var categories = [ 'F', 'C', 'A1', 'A2', 'A3' ].map(function (category) {
return businesses.filter(function (business) {
return business.category === category;
});
});
So the missing step in the answer given here was HOW the map would be implemented and HOW the JS snippet could be implemented. Anyway, I ended up having to ask that as a separate question and finally got a nice working example for an answer.
Russ wrote:
The code given looks most likely to be
using the jQuery JavaScript library
that has some useful functions such as
map() for manipulating arrays.
If we go back to the original problem,
you need to order a list of categories
based on the client's preference.
Let's create a an object literal to
map the ordering
var map = {
F : 5,
C : 3,
A1 : 1,
A2 : 4,
A3 : 2
}
We can use this map to order the array
using the sort method
var array = ['F', 'C', 'A1', 'A2', 'A3'];
array.sort(function(a,b) {
return map[a] - map[b];
});
This returns us ["A1", "A3", "C", "A2", "F"]
Anyway, I wanted to make sure this was included on this thread for anyone searching for this issue in the future or anyone following along right now. Thanks for everyone's input!

Categories

Resources