react , using <br> inside .map inside for (object) - reactjs

I know in react you can't use <html> like strings, i'm looking for a solution but i don't see clear, how in this complex logic you can to insert a <br/> object and not like string, because variable 'newvalue' need to store and conditionally add br to separate elements in rows.
let values = JSON.parse(value);
let newvalue = '';
values.map((item) => {
for (const key in listViewField.subfields) {
let nameField = key;
if (typeof item[nameField] !=='undefined') {
newvalue += item[nameField]+ ' ';
}
}
// if (newvalue.trim() !=='') newvalue += '<br/>'; // doesn't work
});
value = newvalue;
return <div key={keyIndex}>{value}</div>;

Rather than using map, you can just iterate over your values and push them into an array.
let values = JSON.parse(value);
let contents = [];
for (let value of values) {
contents.push(<span key={value.key}>{value.name}</span>);
if (value.condition) {
contents.push(<br key={`${value.key}-br`} />);
}
});
return <div>{contents}</div>;
Don't forget to add a unique key to each item.

To add different option, if you want to use it with map and your item is simple string, then you can do something like this.
items.map((item, key) => {
<span style={{whiteSpace: 'pre'}} key={key}>{item + '\n'}</span>
});
Note that I have added style={{whiteSpace: 'pre'}} and + \n

Related

Split a JSON object by parameters

I have a JSON Object defined in Typescript, I want to split it into parts but I can only get the keys:
This is my JSON object:
let data = {
"dataTest": "data1,data2,data3",
"insTest": "ins1,ins2,ins3",
"serTest": "ser1,ser2,ser3"
}
This is what I do to loop through it:
for (let key of Object.keys(data)) {
console.log(key)
}
This is what I get:
1º //dataTest
2º //insTest
3º //serTest
This is what I want to get:
1º //dataTest: "data1,data2,data3"
2º //insTest: "ins1,ins2,ins3"
3º //serTest: "ser1,ser2,ser3"
Upgrade
Is it also possible to get the concatenation of all the values in a single array?
Example:
data1,data2,data3,ins1,ins2,ins3,ser1,ser2,ser3
Use Object.entries().
The Object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
const data = {
dataTest: "data1,data2,data3",
insTest: "ins1,ins2,ins3",
serTest: "ser1,ser2,ser3"
};
const entries = Object.entries(data);
entries.forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
You can get the required value using Object.entries().
let data = {
"dataTest": "data1,data2,data3",
"insTest": "ins1,ins2,ins3",
"serTest": "ser1,ser2,ser3"
}
Object.entries(data).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
Here is another way
for(let key in data) {
console.log(key + ': ' + '"' + data[key] + '"');
}
using Template literals
for(let key in data) {
console.log(`${key}: "${data[key]}"`);
}

react check array values based on specific keys returning true/false if values found

I am trying to figure out how to do this but can't seem to wrap my head around it..
I have an address object
const obj = {
"address_type":"Home",
"country":"US",
"addressLine1":"123 Any Street",
"addressLine2":"",
"city":"Any Town",
"state":"Indiana",
"state_code":"IN",
"zip":"46220-4466",
"phone":"6715551313",
"mobile_number":"",
"extn":"",
"fax":"",
"county_name":"MyCounty"
}
I want to check for any key that has a value but only specific keys
const objProps = ["addressLine1","addressLine2","city","state_code","zip","county_name"];
I want to check all keys in objProps against my address object and if any one of them contains a value return true (doesn't matter if its 1 or all 6).. If all keys don't contain a value then return false (Sometimes I will get an address object that has all null values)
I've tried various ways to accomplish this but have failed in each one.
The variation I am working on now is using reduce. While it doesn't meet my needs I thought I could check the resulting array and if length was greater than 0 than I have my answer..
Work-in-progress:
function hasAddressData(obj: any) {
const objProps = ["addressLine1","addressLine2","city","state_code","zip","county_name"];
const keysWithData = objProps.reduce((accumulator, key) => {
const propExistsOnObj = obj.hasOwnProperty(key);
let keyHasData = [];
if (obj[key].length > 0 ) {
keyHasData = obj[key]
}
if (!propExistsOnObj) {
accumulator.push(key);
} else if (keyHasData) {
const equalValueKeyIndex = accumulator.indexOf(key);
accumulator.splice(equalValueKeyIndex, 1);
}
return accumulator;
});
return keysWithData;
}
The above is messed up I know and doesn't work.. Just learning this stuff.. anyone have a suggestion or comment?
Check that .some of the objProps, when looked up on the obj, contain a value. (Either with Boolean or by comparing against '')
const obj = {
"address_type":"Home",
"country":"US",
"addressLine1":"123 Any Street",
"addressLine2":"",
"city":"Any Town",
"state":"Indiana",
"state_code":"IN",
"zip":"46220-4466",
"phone":"6715551313",
"mobile_number":"",
"extn":"",
"fax":"",
"county_name":"MyCounty"
}
const objProps = ["addressLine1","addressLine2","city","state_code","zip","county_name"];
const somePopulated = objProps.some(prop => obj[prop]);
// or prop => obj[prop] !== ''
console.log(somePopulated);
const obj = {
"address_type":"Home",
"country":"US",
"addressLine1":"",
"addressLine2":"",
"city":"",
"state":"Indiana",
"state_code":"",
"zip":"",
"phone":"6715551313",
"mobile_number":"",
"extn":"",
"fax":"",
"county_name":""
}
const objProps = ["addressLine1","addressLine2","city","state_code","zip","county_name"];
const somePopulated = objProps.some(prop => obj[prop]);
// or prop => obj[prop] !== ''
console.log(somePopulated);
function checkKeys(target, props) {
return props.some((prop) => {
return target.hasOwnProperty(prop) && target[prop];
});
}
Explanation: some iterates through the props you want to check, returning true immediately when one is found (i.e. the callback returns true). If no props are found (i.e. no callback returns true), some returns false.
hasOwnProperty ensures that you are only checking properties on target, and not looking up the prototype chain. target[prop] checks for a truthy value. You may need to modify this last check if you're going to be handling values other than strings.

Functional component returns object Object in react

I want to output the values of a json object. On each fetch, the type of values change from string to null. That's why I have the for loop and the if statement. Each constant inside the loop outputs the correct value but after it is added to listItems each <li> just returns [object Object].
I tried using <li>${value} (${time})</li> but this outputs the tags <li> as a string value.
function ValuesList(props) {
let listItems = '';
for(let i=1; i<=15; i+=1){
const value = props.myDrink[`strValue` + i]; *//json code is: strValue1, strValue2, ... strValue15, with some of null value.*
const time = props.myDrink[`strTime` + i];
if (typeof value === 'string'){
listItems += <li>{value} ({time})</li>
}
}
return (<ul>{listItems}</ul>)
};
I have done this in jQuery before but I need to make it work in react. Should I change the +=? If not, what line should I fix? This is part of my first react project. Please help, thank you :)
Rather than concatenating JSX values into an empty string, push them into an array (with a key attribute):
let listItems = [];
for(let i=1; i<=15; i+=1){
const value = props.myDrink[`strValue` + i];
const time = props.myDrink[`strTime` + i];
if (typeof value === 'string'){
listItems.push(<li key={/* some unique key. Probably your value */}>{value} ({time})</li>);
}
}
You should directly map your items. There is no need to do what you used to do in jQuery.
if your drinks prop is an array
return (
<ul>
{props.drinks(map(({value, time}, i)=>{
if (typeof value === 'string'){
return <li key={`item-${i}`}>{value} ({time})</li>
}
})
</ul>
)
if your drinks props is an object
return (
<ul>
{Object.entires(props.drinks).map(({ value, time }, i) => {
if (typeof value === "string") {
return <li key={`item-${i}`}>{value} ({time})</li>;
}
})}
</ul>
)

Replace index in array

I'm trying to understand how array works in typescript and I'm struggling to find any solutions on how to replace the index inside an array by a variable, for example with the datas as show below I would like to replace all index numbers by the part_id variable that is inside each index :
As an example, for the first index, instead of [0] I want to have 26 which is the part_id etc...
Here's a code samplet ( datas come from an API, I take a copy of the array returned by the API and modify it so that I can do a forEach on them and PatchValue is to set the values onInit)
Component.ts
initQuot(){
this.service.checkExistQuot().subscribe(res => {
this.quotArray = res;
this.quotDetails = res.quotation.quotationdetail;
let group = {};
this.copy.forEach((val, index)=>
{
group[`longueur_${index}`] = '';
group[`quantity_${index}`] = '';
group['diameter1'] = '';
group['diameter2'] = '';
});
this.dropForm = this.formBuilder.group(
group
);
this.quotDetails.forEach( (myArray, index) => {
this.copy.forEach( array1Ttem => {
this.quotDetails.forEach( array2Item => {
if(array1Ttem.part_id == array2Item.part_id){
for (var i = 0; i < this.copy.length; i++) {
this.copy[myArray.part_id] = this.copy[index];
console.log(this.copy);
let patchValue = {};
this.copy[i].longueur = myArray.longueur;
this.copy[i].quantity = myArray.quantity;
patchValue[`longueur_${index}`] = this.copy[index].longueur;
patchValue[`quantity_${index}`] = this.copy[index].quantity;
this.dropForm.patchValue(patchValue);
}
}
else{
console.log("No values matched");
}
})
});
})
})
}
If anyone knows a solution/what should I look at the help my issue I would really appreciate it, thank you
It's not really feasible to alter the array indices, but you could achieve essentially any desired behaviors using array functions. For instance, if you want to order the array by the part_id, you could do list.sort((a, b) => (a.part_id > b.part_id) ? 1 : -1)
It could be asking if the index value of an array, once declared to start at 0, could be changed to 1. The answer to that is no.
Sorting the actual array is the best solution in your case:-
list.sort((a,b) => a.part_id - b.part_id);

Searching JSON array using another JSON array node js

I'm trying to filter a JSON array using another JSON array criteria that I have using (filter).
Here is my code:
function filterArray(object, criteria){
return object.filter(function(obj){
for(var i=0;i<criteria.length;i++){
let criteriaEle = criteria[i];
return Object.keys(criteriaEle).forEach(function(key){
if(obj[key] == criteriaEle[key]){
return obj;
}
})
}
})
}
For example:
object = [{type:1,company:1,color:0,name:a},{type:2,company:1,color:0,name:b},{type:1,company:3,color:0,name:c},{type:4,company:1,color:0,name:d},{type:1,company:1,color:1,name:e}]
criteria = [{type:1,company:1,color:0},{type:1,company:1,color:1}]
So if I give these two arrays to the function it should return
obj = [{{type:1,company:1,color:0,name:a},{type:1,company:1,color:1,name:e}}]
I'm not sure where am I going wrong in this. Please help.
Update:
Also, I do not want to use obj.type or obj.company or object.color as parameters to search as I want to make my code maintainable and do not want to come and update it later if in future more criteria's are added.
const data = [{type:1,company:1,color:0,name:'a'},{type:2,company:1,color:0,name:'b'},{type:1,company:3,color:0,name:'c'},{type:4,company:1,color:0,name:'d'},{type:1,company:1,color:1,name:'e'}];
const criteria = [{type:1,company:1,color:0},{type:1,company:1,color:1}];
function checkCriteria(obj) {
return criteria.some(criterion => {
for (const key in criterion) {
if (criterion[key] !== obj[key]) {
return false;
}
}
return true;
});
}
const filtered = data.filter(checkCriteria);
console.log('Filtered array: ', filtered);
Here is one solution.
Here are some references
Array.some
Array.filter
Based on the comment, adding another snippet to explain the concept of closures.
const data = [{type:1,company:1,color:0,name:'a'},{type:2,company:1,color:0,name:'b'},{type:1,company:3,color:0,name:'c'},{type:4,company:1,color:0,name:'d'},{type:1,company:1,color:1,name:'e'}];
function createCriteriaValidationFunction(criteria) {
return function checkCriteria(obj) {
return criteria.some(criterion => {
for (const key in criterion) {
if (criterion[key] !== obj[key]) {
return false;
}
}
return true;
});
}
}
const criteria = [{type:1,company:1,color:0},{type:1,company:1,color:1}];
const filtered = data.filter(createCriteriaValidationFunction(criteria));
console.log('Filtered array: ', filtered);
It's the same concept as before, however, criteria was defined in the file. This time, criteria can be defined outside and can be passed in to the function. The trick is to create the checkCriteria function on the fly with criteria passed in and available in the closure. In both cases, criteria variable is available in the scope in which checkCriteria is executed.

Resources