I need to print in my list all the items of my array, but I'm getting only the last item printed. When I console.log it, I can see all the items. Not sure why this is happening, I tried to figure out using all I've got, but none worked.
let examples = [];
onMount(async () => {
const response = await fetch(
"https://<my-api>/db/v1/cosmos/{container}",
{
method: "POST",
headers: {
"<api-key>":
"<my-api-key>",
},
body: JSON.stringify({
query: "SELECT * FROM c ORDER BY c.name ASC",
}),
}
).then((response) => response.json());
for (let i = 0; i < response.data.length; i++) {
console.log(response.data[i].name);
examples = response.data[i].name;
}
});
On my HTML I'm using the following loop:
{#each examples as example}
<ListgroupItem class="text-base font-semibold gap-2">
Name: {examples} <br />
</ListgroupItem>
{/each}
What I'm getting in return, is just only the last item of my array. If I use example instead of examples, on my foreach loop, my return is only the letters.
When I'm using SvelteKit and Cosmos DB.
Something I don't get is that if the item has 5 letters, it will print 5 rows. If another item has 7 letters, it will print 7 rows. Not sure why. I am not getting any error.
Any ideas what I'm doing wrong?
I also have tried using those below, but they didn't work.
examples.unshift(0);
examples.push(examples);
You are always assigning to what is supposed to be a list, the name of the current item, so at the end you are left with just the name of the last item:
for (let i = 0; i < response.data.length; i++) {
console.log(response.data[i].name);
examples = response.data[i].name;
}
If you only want a list of name this should be replaced with:
examples = response.data.map(x => x.name)
The #each is also wrong, it iterates the variable but you are not using the item, but the list variable, it should be:
{#each examples as example}
<ListgroupItem class="text-base font-semibold gap-2">
Name: {example} <br /> <!-- example, not examples -->
</ListgroupItem>
{/each}
(As examples was just a string before, it iterated the letters in the string.)
Related
I am using a div that contains an image below which rows are added with products in them. The product gallery must look like a pyramid so below the image there will be three product rows each containing one, two and three products (each product being a custom rfce), respectively.
Illustration:
img
div1 => product
div2 => product product
div3 => product product product
I used a function that renders a string with all the desired attributes and tried using parse (from html-react-parse) to convert the string to html tags but this method seems slightly unprofessional in addition to which upon attempting to parse the string (which was formatted correctly), I am getting an error.
How can I rectify this, and is there a better method I can use?
string generation method:
const getProducts = () => {
var cur = 0
var gallery = ``
for(var i = 1; i <= 3; i++) {
var prods = ``
for(var j = 0; j < i; j++) {
const product = products[cur++]
// <Product /> is a custom rfce.
prods += `<Product
id = ${product.id}
pname = ${product.pname}
price = ${product.price}
rating = ${product.rating}
pic = ${product.pic}
altPic = ${product.altPic}
/>`
}
gallery += `<div className = 'product_row'>
${prods}
</div>`
}
return ({gallery})
}
method call:
return (
...
<div className = 'product_container'>
<img src = {banner} alt = 'banner' />
{parse(getProducts())}
</div>
...
)
the string is displayed just fine in the body before using parse but upon using it I get the following error after the line const product = products[cur++] in getProducts():
TypeError: product is undefined
Even if I get parse to work, I'd like to use another method as I'm sure there is a cleaner alternative.
Since you know the shape (JSX) you want, I would just hardcode the array chunks. Create a function to render an array into a row, and use the utility for each row, slicing the products state into sub-arrays to be rendered into the rows.
Array.prototype.slice
The slice() method returns a shallow copy of a portion of an array
into a new array object selected from start to end (end not included)
where start and end represent the index of items in that array. The
original array will not be modified.
const renderRow = row => (
<div className='product_row'>
{row.map(product => (
<Product
key={product.id}
id={product.id}
pname={product.pname}
price={product.price}
rating={product.rating}
pic={product.pic}
altPic={product.altPic}
/>
))}
</div>
);
return (
...
<div className = 'product_container'>
<img src={banner} alt='banner' />
{renderRow(products.slice(0,1))}
{renderRow(products.slice(1,3))}
{renderRow(products.slice(3,6))}
</div>
...
);
I have a string called I want to order cheese chicken pizza..
I want to replace cheese with <span style={{color: 'red'}}>cheese</span> and chicken with <span style={{color: 'green'}}>chicken</span>.
So I expect a result like I want to order <span style={{color: 'red'}}>cheese</span> <span style={{color: 'green'}}>chicken</span> pizza.
In an array I have data like let arr = ['cheese', 'chicken']. I took the below approach:-
let text = "I want to order cheese chicken pizza."
arr.map(a=>{
let findText = new RegExp(a, 'g');
text = text.replace(findText, (match)=>(<span>{match}</span>))
});
return text;
I get the result I want to order [object object] [object object] pizza.
I checked maximum solution is for replacing single same string.
I want to achieve this because I will add eventListener to each span tag to get the details.
Can anyone help me out.
Thnaks :)
The challenge, as outlined by Joans, is that you're trying to mix JSX and a string. There are, however, ways around it. The first thing you should do, is convert your array of strings to an object of elements. So this:
let arr = ['cheese', 'chicken']
Should be:
const Elems = {
cheese: (
<span
style={{ color: "red", marginRight: "5px" }}
onClick={() => alert("clicked cheese span")}
>
cheese
</span>
),
chicken: (
<span
style={{ color: "red", marginRight: "5px" }}
onClick={() => alert("clicked chicken span")}
>
chicken
</span>
)
};
Notice how each span element has the onClick attached to them so you can catch the click event. You can add anything else you want.
Then, the idea is to break your text into an array such as:
["I", "want", "to", "order", "cheese", "chicken", "pizza."]
Replace those array elements (cheese and chicken) with the corresponding values inside your Elems object. And then render it. Easy! This function will do that for you:
const swapText = () => {
const text_array = text.split(" ");
const a = text_array.map((item) => {
if (item in Elems) item = Elems[item];
else item += " ";
return item;
});
return a;
};
Then just render it like so:
{swapText().map((item) => item)}
That's it. Here is a Sandbox for you: https://codesandbox.io/s/hardcore-lalande-vxwu6?file=/src/App.js
The issue is that you're dealing with strings and can't insert a span into a string. You could either deal in only JSX or only strings - which is better depends in part on your situation (not sure exactly how you plan on adding the event listener's on the spans). Here is what only strings would look like:
let arr = ['cheese', 'chicken']
let text = "I want to order cheese chicken pizza."
arr.map(a=>{
let findText = new RegExp(a, 'g');
text = text.replace(findText, (match)=>(`<span>${match}</span>`))
});
return text;
I have a for loop that needs to render divs according to some logic:
let allRecords;
if (this.state.allRecords) {
allRecords = (() => {
let paramOne = this.state.paramOne;
let paramTwo = this.state.paramTwo;
let paramThree = this.state.paramThree;
let paramFour = this.state.paramFour;
let paramFive = this.state.paramFive;
let paramSix = this.state.paramSix;
for (let i = 0; i < this.state.length; i++) {
let res;
res = (
<div>
<div className="event-result-table-container">
<div className="result-cell">{paramOne[i]}</div>
<div className="result-cell">
<span>{paramTwo[i] ? "Win" : "Lose"}</span>
</div>
<div className="result-cell">{paramThree[i]}</div>
<div className="result-cell">{paramFour[i]}</div>
<div className="result-cell">{paramFive[i]}</div>
<div className="result-cell-last">{paramSix[i]}</div>
</div>
</div>
);
return res;
}
})();
}
The six param arrays all have a similar structure. For example, I have copied the paramSix state array from the Chrome console, and it looks like this:
[
[
479,
480,
481,
482,
483,
484,
485,
486,
487
]
]
Expected Result: I want to see a bunch of res blocks rendered (equal to this.state.length), each with its correct value taken from the state arrays.
Observed result: Only one row of blocks gets rendered, but all the values are there (checked with React DevTools), as if it renders only one block of divs, but puts all the values in their cells, instead of putting them in separate blocks.
What am I doing wrong here?
The first time you call return in your function it stops executing and returns that value. You're calling it within the for loop, but it doesn't matter because for loops don't work that way, they aren't functions. So the loop doesn't run more than once.
The other issue that you have is that your data, like paramSix that you have showed us, is an array with an array of data, so when you reference paramSix[i] in the first (and only) execution of the loop, you are referencing an array, not a number. Instead you probably want paramSix[0][i].
Here's a way to rewrite it so that an array of elements is created. Please note that I used object destructuring to simplify getting the params from the state, and used const since these values shouldn't be changed here:
let allRecords = [];
if (this.state.allRecords) {
const {
paramOne,
paramTwo,
paramThree,
paramFour,
paramFive,
paramSix
} = this.state;
for (let i = 0; i < this.state.length; i++) {
allRecords.push(
<div>
<div className="event-result-table-container">
<div className="result-cell">{paramOne[0][i]}</div>
<div className="result-cell">
<span>{paramTwo[0][i] ? "Win" : "Lose"}</span>
</div>
<div className="result-cell">{paramThree[0][i]}</div>
<div className="result-cell">{paramFour[0][i]}</div>
<div className="result-cell">{paramFive[0][i]}</div>
<div className="result-cell-last">{paramSix[0][i]}</div>
</div>
</div>
);
}
}
Hopefully this is a easy question, i tried to do what i cound do on my own. But i can't solve the rest part.
Out for every row, i want to check if the date is heigher or lower equels to the last. But how?
As you can see yon on the image and the sample code.
Click and see the image exsample
And the following code:
#using Scoutpocket.Models.Database;
#model Tuple<List<Properties>, List<SubProperties>, List<Rating>>
<div class="container">
#foreach (var item in Model.Item1)
{
<br />
<br />
<b>
#item.PropertiesName
</b>
<br />
foreach (var item2 in item.SubProperties)
{
#item2.SubPropertiesName<br />
int count = 2;
int getLast = 1;
foreach (var item3 in item2.rating.Where(x => x.PlayerID == 1).Take(count).OrderByDescending(x => x.Date))
{
for (int i = 0; i < getLast; i++)
{
// Check the index of the last row, and check if the current date is lower or heighter.
<b>Compare date on last and newst</b>
}
<span>Rating ID: #item3.RatingID</span>
<span> | </span>
<span>Value: #item3.Value</span>
<span> | </span>
<span>ScoutID: #item3.ScoutID</span>
<span> | </span>
<span>PlayerID: #item3.PlayerID</span>
<span> | </span>
<span>Date: #item3.Date</span>
<br/>
}
}
}
</div>
If you're using List types, you can easily use Count to get the size and do list.Count - 1 to get last index. That will return the last element; make sure to validate the count, other wise index out of bounds might be raised.
For instance,
var _dateHigh = Model.Item1.Last(); // extension methods
// same for dateLow
#foreach (var item in Model.Item1) {
// run the code here.
}
If the last element changes with each iteration, then I recommend using a nested variable in the loop. We cannot help much, as you did not share the model structures, so there is very much less that we can help with.
How can I find the last element in a List<> ?
I need to reorder li containing unique same-length text based on position of identical unique same-length semicolon-delimited text found in a separate string, as in following example:
li elements ...
<ul>
<li><span>28dg4</span></li>
<li><span>jjk63</span></li>
<li><span>HN3gE</span></li>
<li><span>k213C</span></li>
</ul>
... sorted by order of semicolon delimited substrings (left to right),
<div id="string">HN3gE;28dg4;k213C;jjk63</div>
... must reorder li like this:
<ul>
<li><span>HN3gE</span></li>
<li><span>28dg4</span></li>
<li><span>k213C</span></li>
<li><span>jjk63</span></li>
</ul>
I've set up a fiddle but can't formulate the approrpiate comparison function (new to me):
http://jsfiddle.net/ysec0ydp/16/
Maybe I cannot use sort and should use something else? I haven't found anything on here or elsewhere that does specifically what I want ;-(
Thx for pointers.
UPDATE
The following code outputs the proper order of string, but doesn't display as appended li:
<div id="string">tree$1234567890;boat$4567321890;9876512340;1736925408</div>
<ul>
<li><span>1234567890</span></li>
<li><span>1736925408</span></li>
<li><span>4567321890</span></li>
<li><span>9876512340</span></li>
</ul>
var ul = $('ul');
var li = ul.children("li");
var my_list = li.map(function() {
return $(this).find('span').text();
}).get();
var my_string = $.map($("#string").text().split(/;/), function (t) {
return t.replace(/^.*\$/, "");
});
li.detach();
temp = [];
for (i = 0; i < my_string.length; i++) {
for (j = 0; j < my_list.length; j++) {
if ( my_string[i] == my_list[j] ) {
temp.push(my_list[j]);
}
}
}
$("ul").append( temp );
// RESULT is one li: 1234567890456732189098765123401736925408
// instead of the 4 reordered li: 1234567890
4567321890
9876512340
1736925408
How can this be fixed? See fiddle: http://jsfiddle.net/ysec0ydp/19/
Here you go:
var orderBy = $('#string').text().split(';');
var $newUl = $('<ul></ul>');
var $myList = $('#my-list'); // gave id="my-list" to your list to identify it.
orderBy.forEach(function(key){
$newUl.append($myList.find('li').filter(function(idx, li){ return $(li).text() === key; }).detach());
});
$myList.append($newUl.html());
I took the liberty of giving an id to your list to identify it.
Fiddle here.