Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot read property 'mainScreen' of undefined - when trying to get dark mode status #275

Open
butaminas opened this issue Sep 13, 2020 · 10 comments

Comments

@butaminas
Copy link

butaminas commented Sep 13, 2020

Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 7.0.8
  • Cross-platform modules: "@nativescript/firebase": "rc"
  • Android Runtime: -
  • iOS Runtime:
Installing on device E2CFC71D-3295-443F-B505-B3B83D45553F...
Successfully installed on device with identifier 'E2CFC71D-3295-443F-B505-B3B83D45553F'.
Restarting application on device E2CFC71D-3295-443F-B505-B3B83D45553F...
Successfully synced application org.nativescript.aaa on device E2CFC71D-3295-443F-B505-B3B83D45553F.
(RunningBoardServices) [com.apple.runningboard:connection] Identity resolved as application<org.nativescript.aaa>
***** Fatal JavaScript exception - application has been terminated. *****
NativeScript encountered a fatal error: Uncaught TypeError: Cannot read property 'mainScreen' of undefined
at
../node_modules/@nativescript/theme/index.js(file: node_modules/@nativescript/theme/index.js:25:33)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at ../node_modules/babel-loader/lib/index.js!../node_modules/vue-loader/lib/index.js?!./components/Home.vue?vue&type=script&lang=js&(file:///app/bundle.js:42:77)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at ./components/Home.vue?vue&type=script&lang=js&(file: app/components/Home.vue?5625:1:0)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at ./components/Home.vue(file: app/components/Home.vue:1:0)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at (file: app/app.js:1:0)
at ./app.js(file:///app/bundle.js:403:30)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at checkDeferredModules(file: app/webpack/bootstrap:43:0)
at webpackJsonpCallback(file: app/webpack/bootstrap:30:0)
at (file:///app/bundle.js:2:57)
at require(:1:137)
(CoreFoundation) *** Terminating app due to uncaught exception 'NativeScript encountered a fatal error: Uncaught TypeError: Cannot read property 'mainScreen' of undefined
at
../node_modules/@nativescript/theme/index.js(file: node_modules/@nativescript/theme/index.js:25:33)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at ../node_modules/babel-loader/lib/index.js!../node_modules/vue-loader/lib/index.js?!./components/Home.vue?vue&type=script&lang=js&(file:///app/bundle.js:42:77)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at ./components/Home.vue?vue&type=script&lang=js&(file: app/components/Home.vue?5625:1:0)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at ./components/Home.vue(file: app/components/Home.vue:1:0)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at (file: app/app.js:1:0)
at ./app.js(file:///app/bundle.js:403:30)
at __webpack_require__(file: app/webpack/bootstrap:74:0)
at checkDeferredModules(file: app/webpack/bootstrap:43:0)
at webpackJsonpCallback(file: app/webpack/bootstrap:30:0)
at (file:///app/bu<…>

  • Plugin(s):
    "@nativescript/core": "~7.0.0",
    "@nativescript/firebase": "rc",
    "@nativescript/theme": "nativescript-vue" (tried with rc also),
    "nativescript-vue": "~2.8.0"

Describe the bug
Pretty much stock nativescript-vue installation with NativeScript CLI 7.0.8.
In my main screen I import the theme using import Theme from "@nativescript/theme";
Then I'm trying to get the dark mode status like this:

mounted () {
      console.log(Theme.getMode())
},

I get an error:
(CoreFoundation) *** Terminating app due to uncaught exception 'NativeScript encountered a fatal error: Uncaught TypeError: Cannot read property 'mainScreen' of undefined

To Reproduce
Just try to use Theme.getMode() on NativeScript 7 with Vue (might be the same with others as well)

Expected behavior
Haven't used this feature before, I guess it will give you a string of "ns-light" or "ns-dark" and won't break your app.

Sample project
Can't reproduce this on play.nativescript.org as it uses the old NativeScript. As far as I've tested it seems to be the issue only with NativeScript 7

@martijnvanschie
Copy link

Same for me. Tried both a Angular Template and a few minutes ago a Core template. Both same error message.

@martijnvanschie
Copy link

This issue is still hunting me even after updating to 2.3.3 (which seems to fix it for some people) and the dark theme is really making my app unusable. Any progress on this?

@martijnvanschie
Copy link

So after looking a litthe further if found out that there is actually a new version of the Theme packages that support {N}7. I used the RC version ("@nativescript/theme": "^2.5.0").

An up-to-date listing of NativeScript plugins with 7.0 compatibility that we know of
@nativescript/theme

After upgrading to this version the issue is gone and i can now use the light theme. Currently i can only implement a toggle button that works. Can not get the app to start in Light mode. Somehow the app loads in Dark Mode as this is currently my settings on the phone.

If i can get the app to also START in light mode i'm completely happy :)

@butaminas
Copy link
Author

@martijnvanschie updating to RC also does the trick for me.

You can try adding this to your info.plist:
...
<key>UIUserInterfaceStyle</key>
<string>Light</string>
...

This would force the light mode by default as mentioned here: https://docs.nativescript.org/ui/dark-mode

@butaminas
Copy link
Author

After working on it a bit more, I've noticed that Theme.getMode() is not working properly. Even if I start in dark mode, I always get ns-light.

The systemAppearanceChanged event works fine on the other hand. But I need to know the appearance when the app is launched.

This is most likely an old issue that is mentioned here: #232 where the solution was to use Application.systemAppearance() as an alternative, however, this also doesn't work as I end up with (CoreFoundation) *** Terminating app due to uncaught exception 'NativeScript encountered a fatal error: Uncaught TypeError: Cannot read property 'substr' of undefined error.

@butaminas
Copy link
Author

Here is my workaround for the above problem. Note, this is not a solution and this still needs to be fixed but since I was struggling with this a lot it might be useful for someone else also:

import { Application, isIOS } from "@nativescript/core"
import store from "../index"

Application.on(Application.displayedEvent, (args) => {
    if (isIOS) {
        store.commit('generalStore/setDarkMode', Application.ios.systemAppearance)
    } else {
        store.commit('generalStore/setDarkMode', Application.android.systemAppearance)
    }
});

P.S. I'm using nativescript-vue and Vuex but the idea is clear - you go for Application.ios.systemAppearance or Application.android.systemAppearance.

IMPORTANT: you need to run it in displayedEvent or do a manual timeout, otherwise it will not work.

@martijnvanschie
Copy link

Thanx for the updates @butaminas.

I've been playing around some more with this code and found still strange behaviour. When changing the theme on my phone the {N} Theme stays the same. This is is my debugging code

Application.on(Application.systemAppearanceChangedEvent, (args: SystemAppearanceChangedEventData) => {
    console.log('systemAppearanceChangedEvent', args.newValue);
    console.log('Theme.getMode', Theme.getMode());
});

The output is al follows (When switching from Dark to Light and back)

JS: systemAppearanceChangedEvent light
JS: Theme.getMode ns-light
JS: systemAppearanceChangedEvent dark
JS: Theme.getMode ns-light

Also, setting mode to light in my main.ts requires a timeout to be set.

Below code does not set the {N} Theme

Theme.setMode(Theme.Light);

It required a (very short) timeout to make it work

setTimeout(() => {
    console.log('Setting mode to light');
    Theme.setMode(Theme.Light);
  },100);

So i kinda have it working now, but I keep on investigating :)

PS: I'm using {N}7 Angular

@butaminas
Copy link
Author

@martijnvanschie it's definitely a bug that seems to be around for quite a while. From what I came to realize is that at this point, you can't use Theme.getMode() at all as it is not functioning properly.

Currently, the only solution that is working is Application.ios.systemAppearance and Application.android.systemAppearance as I mentioned in the previous post. This returns the correct value at launch (at least with all the tests I was able to make) and systemAppearanceChangedEvent also seems to be returning the correct value.

And yes, it also doesn't work for me without a delay. Setting everything to run at displayedEvent seems to be enough of a delay for everything to work properly, so I guess it makes sense that Theme.setMode would also require a delay to work.

If you find anything else worth mentioning - let me and the community know as I think this is uncharted waters for most of us. Hopefully these "hacks" will stay stable and do the trick until the core is fixed.

@martijnvanschie
Copy link

I'll take a look at that displayEvent again and test it out.

I do have another issue which is must more annoying than the hacks. When i go from light back to dark mode on my phone (Galaxy S20+) the app stays in dark mode. Even my test button to setMode() of toggleMode() wont work anymore, dark mode it is from that point on untill i restart the app again. Not a use case that is often performed i quess but one that should work as we developers do test the less obvious use cases :)

Think i'll raise a seperate issue for this but the issues keep stacking and it does not seem to be picked up. I understand it's busy and probably due to the {N}7 upgrade as well.

@butaminas
Copy link
Author

That's strange. I've tried switching dark / light mode on Xiaomi Redmi Note 8 and the appearance in the app is changing accordingly.

Will try to test this out on raw Android to see if I get different results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants