So I am working with a tsx file and I tried to push some html into a variable with options in it that takes their value from foreach item and so far so good but then I try to push them into some array and use it in my state in order to do the right thing for react it pushes undefined. ı am confused how it gives undefined when I try to push it into array and it gives value when I try to push it into html element
provider.getItems().then((items:any[]) => {
items.forEach((item) => {
this.categoryOptItems.push(item.Title);
this.categoryOpts.push(<option value={item.Title}>{item.Title}</option>)
})
this.setState({categories:
this.categoryOptItems
})
})
I found my solution but not sure if it is the best way though.
This is in componentDidMount
provider.getItems().then((items:any[]) => {
items.forEach((item) => {
categoryOptItems.push(item.Title);
})
this.setState({categories:
categoryOptItems
})
})
This is the function
options() {
var categories = this.state.categories;
const html:any = [];
for (var i = 0; i < this.state.categories.length; i++) {
html.push(<option value={i+1}>{categories[i]}</option>);
}
return html;
}
Related
I am pushing Div element in an array and then iterating each one by one, but when I came out of first each section the array length becomes 0 and i am unable to enter into for loop.
in for loop, i want to click a section in each div and perform an assertation and go back to the previous section.
let Array =[]
cy.get('.tag-wrapper-item').each(($pills) => {
cy.log($pills)
// cy.log('Success')
Array.push($pills)
cy.log(Array.length)
})
cy.log(Array.length)
for (const element of Array) {
cy.wrap(element).click()
cy.wrap(element).find('.--tag.tag-link.--active.tag-selector-button-link').click()
var OneOffModel = element.text()
cy.get('.heading-markdown').contains(OneOffModel)
cy.go('back')
}
A better approach might be to get the count of .tag-wrapper-item and loop on that
cy.get('.tag-wrapper-item')
.its('length')
.then(count => {
for (let index = 0; index < count; index++) {
cy.get('.tag-wrapper-item').eq(index)
.click()
cy.get('.tag-wrapper-item').eq(index)
.find('.--tag.tag-link.--active.tag-selector-button-link')
.click()
cy.get('.tag-wrapper-item').eq(index)
.invoke('text')
.then(OneOffModel => {
cy.get('.heading-markdown').contains(OneOffModel)
})
cy.go('back')
}
})
If you alias each element in the loop, Cypress will try to overcome the detached-from-DOM error when you read the alias
cy.get('.tag-wrapper-item')
.its('length')
.then(count => {
for (let index = 0; index < count; index++) {
cy.get('.tag-wrapper-item').eq(index)
.as('current')
.click()
cy.get('#current')
.find('.--tag.tag-link.--active.tag-selector-button-link')
.click()
cy.get('#current')
.invoke('text')
.then(OneOffModel => {
cy.get('.heading-markdown').contains(OneOffModel)
})
cy.go('back')
}
})
Cypress commands asynchronous, so at the time the Cypress walks through your array, it's not yet been initialized.
To fix this, you can wrap your code with a then callback:
let Array =[]
cy.get('.tag-wrapper-item').each(($pills) => {
cy.log($pills)
// cy.log('Success')
Array.push($pills)
cy.log(Array.length)
})
cy.then(() => {
cy.log(Array.length)
for (const element of Array) {
cy.wrap(element).click()
cy.wrap(element).find('.--tag.tag-link.--active.tag-selector-button-link').click()
var OneOffModel = element.text()
cy.get('.heading-markdown').contains(OneOffModel)
cy.go('back')
}
})
this.crudService.get('user.php?mode=test')
.subscribe((data:any) => {
{ for (var key in data) { this[key] = data[key]; } };
}
);
This use to work on angular 7 now on angular 13 i get this error (look image)
In template i was using the values for example in json string was and array and i had users, in template was {{users}} , {{posts}} etc.. now the this[key] give error , please help me out its very important can't find solution
i'll show an example code, and then applied to your code:
Example
// creating global variables to receive the values
users: any = null;
posts: any = null;
// simulating the data you will receive
data: any[] = [
{users: ['user1', 'user2', 'user3']},
{posts: ['post1', 'post2', 'post3']}
];
getCrudService() {
// access each object of the array
this.data.forEach(obj => {
// getting keys name and doing something with it
Object.keys(obj).forEach(key => {
// accessing global variable and setting array value by key name
this[String(key)] = obj[String(key)]
})
})
}
Apllied to your code
this.crudService.get('user.php?mode=test').subscribe((data:any) => {
data.forEach(obj => {
Object.keys(obj).forEach(key => {
this[String(key)] = obj[String(key)]
});
});
});
I hope it helped you, if you need help, just reply me.
Hello I am trying to map through an array of objects and push them to a new array.
My ISSUE : only the last item of the object is being pushed to the new array
I believe this has to do with React life cycle methods but I don't know where I should I loop and push the values to the array to get the full list
//My object in an array named states
var states = [{"_id":"Virginia","name":"Virginia","abbreviation":"VN","__v":0},{"_id":"North Carolina","name":"North Carolina","abbreviation":"NC","__v":0},{"_id":"California","name":"California","abbreviation":"CA","__v":0}];
export function StateSelect()
{
**EDIT 1**
const options = [];
function getStates()
{
//This is how I am looping through it and adding to an array
{ states.length > 0 &&
states.map(item =>
(
console.log(`ITEM: ${JSON.stringify(item)}`),
options.push([{ value: `${item.name}`, label: `${item.name}`}])
))
}
}
return( {getStates()}: );
}
Thank you
It looks like your getStates() might not even be returning anything... but assuming it is, I believe you should be able to accomplish this using a forEach() fn in order to push values into your options array... Try adding the following into your map:
states.map((item) => {
console.log(`ITEM: ${JSON.stringify(item)}`);
let processed = 0;
item.forEach((i) => {
options.push([{ value: `${i.name}`, label: `${i.name}`}]);
processed++;
if(processed === item.length) {
// callback fn, or return
}
}
.map usually used to return another result, you could just use .forEach
In fact, you don't really need to declare options at all, just use .map on state to return the result would be fine.
return states.length > 0 && states.map(({ name }) => {
return { value: name, label: name };
});
I'm storing an array of objects in AsyncStorage and would like to know the best way to remove a specific object. Right now I´m passing an id to my function and then I loop through the array to match the id and remove the object and then the array in AsyncStorage is updated. This seems to work ok, but I wonder if this is optimal or if there is a better way to do this?
My function right now:
export function removeData(id) {
AsyncStorage.getItem('#books')
.then((books) => {
const updatedBooks = (JSON.parse(books))
for (let i = 0; i < updatedBooks.length; i++) {
if(updatedBooks[i].id == id) {
updatedBooks.splice(i, 1);
}
}
AsyncStorage.setItem('#books', JSON.stringify(updatedBooks));
})
}
My function for adding data to AsyncStorage:
export function addData(book) {
AsyncStorage.getItem('#books')
.then((books) => {
const b = books ? JSON.parse(books) : [];
b.push(book);
AsyncStorage.setItem('#books', JSON.stringify(b));
});
}
Button to add data with sample data to show structure:
<Button
title = "Add book"
onPress={() => addData({
id: 1,
title: 'Harry Potter',
author:'J.K. Rowling',
thumbnail:'https://covers.openlibrary.org/w/id/7984916-M.jpg',
})
To remove single item
AsyncStorage.removeItem('key', (err) => {
// key 'key' will be removed, if they existed
// callback to do some action after removal of item
});
To remove multiple items
let keys = ['k1', 'k2'];
AsyncStorage.multiRemove(keys, (err) => {
// keys k1 & k2 removed, if they existed
// callback to do some action after removal of item
});
Reference:
RemoveItem method
MultiRemove method
I have the following method which isn't working correct:
getProducts(): Observable<Product[]> {
let PRODUCTS: Product[];
this.http.get(this.base_url + "api/products")
.subscribe(
(data) => {
for(var i in data) {
PRODUCTS.push(new Product(data[i].id, data[i].name, data[i].category, data[i].description, data[i].price, data[i].amount));
}
},
(error) => {
console.log(error);
});
return of(PRODUCTS);
}
The error I'm getting is this:
TypeError: Cannot read property 'push' of undefined
Now, I know that the PRODUCT array is not accessable from within the subscribe function, but I cannot get the correct solution for it.
Can anyone help me with that. I want to return an Observable<Product[]>.
Thank you in advance!
Edit: Updated to account for the fact that the API seems to return an array-like object rather than a true array.
You want to use map:
getProducts(): Observable<Product[]> {
return this.http.get(this.base_url + "api/products")
.map(data => {
let products = [];
for (let i in data) {
products.push(new Product(data[i].id, data[i].name, data[i].category, data[i].description, data[i].price, data[i].amount));
}
return products;
})
.do(null, console.log);
}
Since #pixelbit's comment keeps getting upvotes despite being wrong, here's an example showing why it is wrong:
// Fakes a HTTP call which takes half a second to return
const api$ = Rx.Observable.of([1, 2, 3]).delay(500);
function getProducts() {
let products = [];
api$.subscribe(data => {
for (let i in data) {
products.push(data[i]);
}
});
return Rx.Observable.of(products);
}
// Logs '[]' instead of '[1, 2, 3]'
getProducts().subscribe(console.log);