Converting an ElementHandle to a DOM element using puppeteer? - dom

This is how I currently get each DOM property from an ElementHandle :
let section: ElementHandle = await page.waitForSelector(".selector-list li");
let tagName = await section.$eval('a', (e) => e.tagName);
But here it's tagName. What if I'd like want to inspect further properties ?
I don't want to write $eval for each property.
Question:
How can I convert ElementHandle to a Dom object , so I'd be able
to browse all properties ?
I want to get A as a Dom object.

The better way would be to execute the code on the page via page.evaluate and return the results. That way you can return an array with values:
const result = await page.evaluate(() => {
const elements = document.querySelectorAll(".selector-list li");
// do something with elements, like mapping elements to an attribute:
return Array.from(elements).map(element => element.tagName);
});
result will then be an array with the attribute values of tagName of each element.

Use ElementHandle.evaluate():
const elementHandle = await page.waitForSelector('.selector-list li')
elementHandle.evaluate((domElement) => {
domElement.tagName
// etc ...
})
Typescript:
const elementHandle: ElementHandle = await page.waitForSelector('.selector-list li')
elementHandle.evaluate((domElement) => {
domElement.tagName
// etc ...
})

Related

How to Call Dynamic Variable on Flutter

I have the following code
List toCheck = ['province','regency','district','village'];
List data = [];
toCheck.forEach((value) {
//sample data would looke like (object.province)
if(object.value!=null){ => need to call with object.value
data.add(value);
}
});
If it is in php, that would be look like ${$value}
Try this:
ElevatedButton(onPressed: (){
List toCheck = ['province','regency','district','village'];
List data = [];
toCheck.forEach((value) {
//sample data would looke like (object.province)
if(value!=null){
data.add(value);
}
});
If I understand what you want correctly, this should check if the values of your list are not null, and if so, it will add each value to the data list.

Filter list with whereIn condition in Flutter?

This code sample works fine.
var box = await Hive.openBox<MainWords>('mainWords');
box.values.where((item) {
return item.category == "6" || item.category == '13';
}).toList();
I am trying to filter a list with whereIn condition but it must filter like
List<String> categoryList = ['6', '13'];
var box = await Hive.openBox<MainWords>('mainWords');
box.values.where((item) {
return item in categoryList; // just an examle
}).toList();
How can i achive this?
You should not use the keyword in but the method contains to check if your item exists inside categoryList. Moreover you cannot compare values of different types, I'm seeing that you are returning with box.values an Iterable<MainWords>.
I don't know the content of this class but the item variable is of type MainWords and so it cannot be compared with a String object directly.
I am supposing that you have some access to a String value from your class MainWords so you will need to compare this value with your list.
Code Sample
List<String> categoryList = ['6', '13'];
var box = await Hive.openBox<MainWords>('mainWords');
// As I don't know what are MainWords' properties I named it stringValue.
box.values.where((item) => categoryList.contains(item.stringValue)).toList();

How to get the state from redux-saga select()?

the saga like below.
function *callUserAuth(action) {
const selectAllState = (state) => state;
const tmp = yield select(selectAllState);
console.log(tmp);
}
the console show
enter image description here
how can i get state like
getState["userLoginReducer","isLogin"] in redux ?
i had tried to code like below.
const tmp = yield select(selectAllState._root.entries);
but error is
index.js:1 TypeError: Cannot read property 'entries' of undefine
It seems you are using Immutable.js for your redux state.
The select effect doesn't convert your Immtuable structure to plain javascript. So you need to use methods of Immutable to get to the values you want. To get the whole Immutable state and then convert it to plain javascript object you can do:
function *callUserAuth(action) {
const selectAllState = (state) => state;
const tmp = yield select(selectAllState);
console.log(tmp.toJS());
}
But generally you will probably want to have selectors to get a subset like the isLogin value. In that case you can do this instead:
function *callUserAuth(action) {
const getIsLogin = (state) => state.get('userLoginReducer').get('isLogin');
const isLogin = yield select(getIsLogin);
console.log(isLogin);
}

selector in react-testing-library that can retrieve a number of matches by getAllByText

At the moment I am doing this to pull back all the rows of a table:
const { getByTestId } = renderWithRouter(businessWithContext);
const firstTableRow = await waitForElement(() => getByTestId("row-1-name"));
const secondTableRow = await waitForElement(() => getByTestId("row-2-name"));
expect(firstTableRow.textContent).toBe("test1");
expect(secondTableRow.textContent).toBe("test2");
I would rather do something like this:
const rows = await waitForElement(() => getAllByText(/^row-*/gi));
But I get this error:
Unable to find an element with the text: /^row-*/gi. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
You are using getAllByText but you really want to query by data-testid. This will work:
getAllByTestId(/^row-*/)

AG Grid: Better way for validation row - valueSetter?

Is there a better way to validate a row in ag-grid than with valueSetter?
I can achieve the validation with that but I am not sure, if there is a better way.
https://www.ag-grid.com/javascript-grid-value-setters/#properties-for-setters-and-parsers
I want to validate two fields in the row. DateFrom and DateUntil (they are not allow to be null and DateFrom must be lower than DateUntil).
There are two ways of possible validation handling:
First: via ValueSetter function
and
Second: via custom cellEditor component
I suggest that it would be better to split the logic between custom components, but as you said you need to validate two cell-values between themselves.
On this case from UI perspective you could try to combine them inside one cell and it would be easily to work with values via one component only.
You could override the valueSetter and call the grid api transaction update instead.
Here is pseudo-code that shows how you could implement this.
valueSetter: params => {
validate(params.newValue, onSuccess, onFail);
return false;
};
validate = (newvalue, success, fail) => {
if (isValid(newValue)) {
success();
} else {
fail();
}
};
onSuccess = () => {
// do transaction update to update the cell with the new value
};
onFail = () => {
// update some meta data property that highlights the cell signalling that the value has failed to validate
};
This way you can also do asynchronous validation.
Here is a real example of an async value setter that has success, failure, and while validating handlers that do transaction updates when validation is done.
const asyncValidator = (
newValue,
validateFn,
onWhileValidating,
onSuccess,
_onFail
) => {
onWhileValidating();
setTimeout(function() {
if (validateFn(newValue)) {
onSuccess();
} else {
_onFail();
}
}, 1000);
};
const _onWhileValidating = params => () => {
let data = params.data;
let field = params.colDef.field;
data[field] = {
...data[field],
isValidating: true
};
params.api.applyTransaction({ update: [data] });
};
const _onSuccess = params => () => {
let data = params.data;
let field = params.colDef.field;
data[field] = {
...data[field],
isValidating: false,
lastValidation: true,
value: params.newValue
};
params.api.applyTransaction({ update: [data] });
};
const _onFail = params => () => {
let data = params.data;
let field = params.colDef.field;
data[field] = {
...data[field],
isValidating: false,
lastValidation: params.newValue
};
params.api.applyTransaction({ update: [data] });
};
const asyncValidateValueSetter = validateFn => params => {
asyncValidator(
params.newValue,
validateFn,
_onWhileValidating(params),
_onSuccess(params),
_onFail(params)
);
return false;
};
Here is a code runner example showing this in action: https://stackblitz.com/edit/async-validation-ag-grid-final
Have a look at this two snippets, these come from our internal knowledge base (accessible to customers)
When editing a value in column 'A (Required)', you will see that it does not allow you to leave it empty. If you leave it empty and return the edit, it will be cancelled.
//Force Cell to require a value when finished editing
https://plnkr.co/edit/GFgb4v7P8YCW1PxJwGTx?p=preview
In this example, we are using a Custom Cell Editor that will also validate the values against a 6 character length rule. While editing, if the value is modified outside of 6 characters, it will appear in red, and when you stop editing the row, the value would be reset, so it only accepts a complete edit if the value is valid.
//Inline Validation while editing a cell
https://plnkr.co/edit/dAAU8yLMnR8dm4vNEa9T?p=preview