OnChangeText is not defined on - how can i resolve this error? - expo

Link to my codes (i cant embed images yet) https://i.stack.imgur.com/4XLgU.png
Im trying to add a TextInput Box to my screen but there is an error please tell me how i can resolve it.

Create the two functions and the state for the text and number, please add the below code in your Caloriscreen Class.
const [text,setText] = useState()
const [number, setNumber] = useState()
const onChangeText = (e) =>{
setText(e.target.value)
}
const onChangeNumber= (e) =>{
setNumber(e.target.value)
}

You need to use onChangeText prop properly.
Let's say if we have a state property number which can be created as follows:
constructor(){
super()
this.state={
number:0 }}
And now that you want to store the number user enters in input box you'll have to write:
<TextInput
onChangeText={(text)=>{
this.setState({
number:text
})}}/>

Related

how to implement comparing two screenshots in one test with playwright

I am very new to playwright and i have a problem.
I am trying to implement comparing two screenshots (before and after) in one test.
this is what i want to achieve:
navigate to webpage
take screenshot (before.png)
do some stuff,state changes, etc
take screenshot (after.png)
compare before.png to after.png (if they are the same test should pass, otherwise test fails)
something like this:
test('compare screenshots', async ({ page }) => {
await page.goto('my website here');
const beforeImage = await page.screenshot({
path: `./screenshots/before.png`
})
//
// some state changes implemented here
//
const afterImage = await page.screenshot({
path: `./screenshots/after.png`
})
expect(beforeImage).toMatchSnapshot(afterImage)
});
but it does not work like this.
Any ideas/suggestions how can i achieve this?
Help would be greatly appreciated
You can do something like this:
test('compare screenshots', async ({ page }, testInfo)=>{
await page.goto(pageUrl);
const screenshotTarget = page.locator(scTarget);
await expect(screenshotTarget).toHaveScreenshot( `${testInfo.title}.png`);
//
// some state changes implemented here
//
await expect(screenshotTarget).toHaveScreenshot( `${testInfo.title}.png`);
});
I prefer to use the test titel for naming my screenshots but it should also work if you just enter the same name twice. Then if you run your tests without --update-snapshots they should fail if some visual changes happened.
The problem with Playwright's toHaveScreenshot and toMatchSnapshot is that they're a bit over-engineered and will only compare a current screenshot to a screenshot from a previous test run. If you want to compare two screenshots that you have as Buffers in memory, you can use the getComparator method that Playwright uses behind the scenes:
import { getComparator } from 'playwright-core/lib/utils';
await page.goto('my website here');
const beforeImage = await page.screenshot({
path: `./screenshots/before.png`
});
//
// some state changes implemented here
//
const afterImage = await page.screenshot({
path: `./screenshots/after.png`
});
const comparator = getComparator('image/png');
expect(comparator(beforeImage, afterImage)).toBeNull();
The advantage of using getComparator is that it fuzzy matches, and you can set the threshold of how many pixels are allowed to be different. If you just want to check that the PNGs are exactly identical, a dead simple method to check for equality between the two screenshots is:
expect(Buffer.compare(beforeImage, afterImage)).toEqual(0)
Beware though - this simpler method is flakey and sensitive to a single pixel difference in rendering (such as if any animations/transitions are not completed or if there are differences in anti-aliasing).

How to wait for query to end in aws amplify

I query 'product' on one of my screens using the following function
const getProduct = async () => {
try{
if(userId){
await DataStore.query(Product, c=>c.userID("eq", userId)).then(setProducts)
}
}catch(e){
return
}
};
But what I want is to display something like an activity indicator and wait for the query to finish and then display the products. How can I do this?
Your code above should be inside a useEffect() hook that will run any time the userId changes. That hook can return multiple states: loading, error, the data...
To get the above in a very well tested, easier to read, package with bells & whistles (e.g. caching), look into React Query.
Pseudo-code:
function ExampleComponent() {
const { isLoading, error, data } = useQuery(['products'], () =>
// fetch data here
)
if (isLoading) return 'Loading...'
if (error) return 'An error has occurred: ' + error.message
return (
<div>
<!-- map over your data here -->
</div>
)
}
There is nothing extra needed to enable indicator, it's just a visual representation on the client to show that request is in progress. You can enable indicator before query and set it disabled within the setProducts

Bootstrap 5 hide modal using java script

I open modal using
document.getElementById('openLoginFormBTN').addEventListener('click', function (event) {
let loginFormModal= new bootstrap.Modal(document.getElementById('loginModal'));
loginFormModal.show();
});
and it works fine, but when I want to close it in function
...
console.log("user logged in")
let loginFormModal= new bootstrap.Modal(document.getElementById('loginModal'));
loginFormModal.hide();
...
It doesn't want to close.
I believe you can rely on the getOrCreateInstance method.
No need to retreive the modal again once you have the instance.
const btnShow = document.getElementById('openLoginFormBTN');
const modalEl = document.getElementById('loginModal');
const loginFormModal = bootstrap.Modal.getOrCreateInstance(modalEl);
btnShow.addEventListener('click', function (event) {
loginFormModal.show();
});
loginFormModal.hide();
I created a DEMO where you can play around with this.
Not sure if I've hit the mark on your use case. Please elaborate in case I missed something.

vue testing vuetify input for disabled

I am very new to testing and I'm struggling my way through all this new stuff I am learning. Today I want to write a test for a vuetify <v-text-field> component like this:
<v-text-field
v-model="user.caption"
label="Name"
:disabled="!checkPermissionFor('users.write')"
required
/>
my test should handle the following case:
an active, logged in user has a array in vuex store which has his permissions as a array of strings. exactly like this
userRights: ['dashboard', 'imprint', 'dataPrivacy']
the checkPermissionFor() function is doing nothing else then checking the array above with a arr.includes('x')
after it came out the right is not included it gives me a negotiated return which handles the disabled state on that input field.
I want to test this exact scenario.
my test at the moment looks like this:
it('user has no rights to edit other user overview data', () => {
const store = new Vuex.Store({
state: {
ActiveUser: {
userData: {
isLoggedIn: true,
isAdmin: false,
userRights: ['dashboard', 'imprint', 'dataPrivacy']
}
}
}
})
const wrapper = shallowMount(Overview, {
store,
localVue
})
const addUserPermission = wrapper.vm.checkPermissionFor('users.write')
const inputName = wrapper.find(
'HOW TO SELECT A INPUT LIKE THIS? DO I HAVE TO ADD A CLASS FOR IT?'
)
expect(addUserPermission).toBe(false)
expect(inputName.props('disabled')).toBe(false)
})
big questions now:
how can I select a input from vuetify which has no class like in my case
how can I test for "is the input disabled?"
wrapper.find method accepts a query string. You can pass a query string like this :
input[label='Name'] or if you know the exact index you can use this CSS query too : input:nth-of-type(2).
Then find method will return you another wrapper. Wrapper has a property named element which returns the underlying native element.
So you can check if input disabled like this :
const buttonWrapper = wrapper.find("input[label='Name']");
const isDisabled = buttonWrapper.element.disabled === true;
expect(isDisabled ).toBe(true)
For question 1 it's a good idea to put extra datasets into your component template that are used just for testing so you can extract that element - the most common convention is data-testid="test-id".
The reason you should do this instead of relying on the classes and ids and positional selectors or anything like that is because those selectors are likely to change in a way that shouldn't break your test - if in the future you change css frameworks or change an id for some reason, your tests will break even though your component is still working.
If you're (understandably) worried about polluting your markup with all these data-testid attributes, you can use a webpack plugin like https://github.com/emensch/vue-remove-attributes to strip them out of your dev builds. Here's how I use that with laravel mix:
const createAttributeRemover = require('vue-remove-attributes');
if (mix.inProduction()) {
mix.options({
vue: {
compilerOptions: {
modules: [
createAttributeRemover('data-testid')
]
}
}
})
}
as for your second question I don't know I was googling the same thing and I landed here!

How to get current page from Navigation in ionic 2

I am new to Ionic2, and I am trying to build dynamic tabs based on current menu selection. I am just wondering how can I get current page using navigation controller.
...
export class TabsPage {
constructor(navParams: NavParams,navCtrl:NavController) {
//here I want to get current page
}
}
...
From api documentation I feel getActiveChildNav() or getActive() will give me the current page, but I have no knowledge on ViewController/Nav.
Any help will be appreciated. Thanks in advance.
Full example:
import { NavController } from 'ionic-angular';
export class Page {
constructor(public navCtrl:NavController) {
}
(...)
getActivePage(): string {
return this.navCtrl.getActive().name;
}
}
Method to get current page name:
this.navCtrl.getActive().name
More details here
OMG! This Really Helped mate, Tons of Thanks! #Deivide
I have been stuck for 1 Month, Your answer saved me. :)
Thanks!
if(navCtrl.getActive().component === DashboardPage){
this.showAlert();
}
else
{
this.navCtrl.pop();
}
My team had to build a separate custom shared menu bar, that would be shared and displayed with most pages. From inside of this menu component.ts calling this.navCtrl.getActive().name returns the previous page name. We were able to get the current page name in this case using:
ngAfterViewInit() {
let currentPage = this.app.getActiveNav().getViews()[0].name;
console.log('current page is: ', currentPage);
}
this.navCtrl.getActive().name != TheComponent.name
or
this.navCtrl.getActive().component !== TheComponent
is also possible
navCtrl.getActive() seems to be buggy in certain circumstances, because it returns the wrong ViewController if .setRoot was just used or if .pop was just used, whereas navCtrl.getActive() seems to return the correct ViewController if .push was used.
Use the viewController emitted by the viewDidEnter Observable instead of using navCtrl.getActive() to get the correct active ViewController, like so:
navCtrl.viewDidEnter.subscribe(item=> {
const viewController = item as ViewController;
const n = viewController.name;
console.log('active page: ' + n);
});
I have tested this inside the viewDidEnter subscription, don't know about other lifecycle events ..
Old post. But this is how I get current page name both in dev and prod
this.appCtrl.getActiveNav().getActive().id
Instead of
...
...
//In debug mode alert value is 'HomePage'
//In production/ signed apk alert value is 'n'
alert(activeView.component.name);
if (activeView.component.name === 'HomePage') {
...
...
Use this
...
...
//In debug mode alert value is 'HomePage'
//In production/ signed apk alert value is 'HomePage'
alert(activeView.id);
if (activeView.id === 'HomePage') {
...
...
Source Link
You can use getActive to get active ViewController. The ViewController has component and its the instance of current view. The issue is the comparsion method. I've came up to solution with settings some field like id:string for all my Page components and then compare them. Unfortunately simple checking function name so getActive().component.name will break after minification.