uirouter/angular-hybrid AoT build bootstrapModuleFactory promise injector fails to get UIRouter - angular-ui-router

I've got a sample uirouter/angular-hybrid app, successfully built with #ngtools/webpack AngularCompiler plugin and running. I've updated the main.aot.ts boot function to use bootstrapModuleFactory and can get the injector from the platformRef available in the promise success handler. But injector.get(UIRouter) fails with "Cannot read property 'config' of null."
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory).then((platformRef) => {
const urlService: UrlService = platformRef.injector.get(UIRouter).urlService;
function startUIRouter() {
urlService.listen();
urlService.sync();
}
platformRef.injector.get<NgZone>(NgZone).run(startUIRouter);
});
I confirmed that the injector.get(NgZone) will succeed and injector.get(UIRouter) will fail. I tried moving the call to injector.get(UIRouter) inside the NgZone run func without success.
I also tried moving the upgrade.bootstrap call into the promise success function above to ensure it had booted first, without fixing the problem.
A simple angularjs component is rendering fine, so the boot process seems to be succeeding, except for not being able to call the listen() and sync() functions on the UIRouter.urlService.
I also confirmed the development config and non-aot production config, for this same sample app, do not have this problem and seem to be working fine.
Using versions:
uirouter/angular-hybrid v6.0.2
angular packages at v7.1.4, but also failed with 6.0.0 (which is the angular version in the package.json in the docs for uirouter/angular-hybrid v6.0.2)
Thanks for any ideas.

The problem was that the config object I was passing to UIRouterUpgradeModule.forRoot was being imported from a file that was using a default export of the object, and the object had a reference to a config function that was not being exported. This combination hid the problem during the build, and resulted in the symptom at runtime of not having the UIRouter object available to the injector.
Replacing the default export with a named export triggered the AOT compiler to complain about the non-exported function reference. Additionally exporting the function then allowed a successful build, a happy injector, and a successful runtime boot.

Related

MikroORM repository throwing Global Context error when debugging in Visual Studio Code

I am trying to use MikroORM repositories, but I keep getting the Global Context validation error when I use them while debugging in Visual Studio Code. I am using the RequestContext middleware, just as the documentation and demo applications suggest. The error does not occur when I run the application in a terminal window instead of by debugging.
I am currently running Visual Studio Code version 1.68.1 on Windows 10, using Node version 18.2.0.
Error Recreation:
Install the sample application Express + MongoDB + JavaScript from the Mikro-orm Example integrations (https://github.com/mikro-orm/express-js-example-app).
Follow the instructions in the README.md to run the application.
Use Postman (or equivalent) to create an author.
3.1. POST http://localhost:3000/author\
3.2. Body (raw/JSON):
{
"name": "test person",
"email": "test#test.com",
"age": 42
}
Use Postman (or equivalent) to retrieve authors.
4.1. GET http://localhost:3000/author
Copy the id of the author you just created.
Use Postman (or equivalent) to update the author.
6.1. PUT http://localhost:3000/author/<id from step 5.>
6.2. Body (raw/JSON):
{
"name": "test 'success' person"
}
NOTE: This will succeed, proving that everything is configured correctly. I have tried this with both the repository's version of Mikro-orm as well as the current latest version (5.2.3).
Stop the application (Ctrl-C in terminal)
Attach the debugger
8.1. Open the file app\server.js
8.2. Open VS Code's Run and Debug panel.
8.3. Click the "Run and Debug" button.
Use Postman (or equivalent) to update the author.
9.1. PUT http://localhost:3000/author/<id from step 5.>
9.2. Body (raw/JSON):
{
"name": "test 'failure' person"
}
This time the update will fail with the message:
"Using global EntityManager instance methods for context specific
actions is disallowed. If you need to work with the global instance's
identity map, use allowGlobalContext configuration option or
fork() instead."
Within the sample application, the error occurs in author.controller.js, within the router.put('/:id', async (req, res) section, specifically on the line await DI.authorRepository.flush() (line 55). However, experimentation suggests that the error will occur the second time you make any repository call. For example, if you duplicate the findOneOrFail line like this:
const author = await DI.authorRepository.findOneOrFail(req.params.id);
const foo = await DI.authorRepository.findOneOrFail(req.params.id);
the error will occur on the second call to .findOneOrFail.
The error is being thrown in #mikro-orm/core/EntityManager.js, in the getContext method (line 737). When the second call to the repository occurs, getContext is called multiple times. The first time has the following call stack
EntityRepository.flush
MongoEntityRepository.em (get)
EntityManager.getContext
This call is successful.
However, the second call to getContext fails. It has this call stack:
EntityRepository.flush
EntityManager.flush
EntityManager.getUnitOfWork
EntityManager.getContext
The issue seems to be that between the two calls to getContext, em._id goes from not 1 to 1. It looks to me like the EntityManager with an _id of 1 is the global context we shouldn't be using. However, when you run the code without debugging, em._id is not 1 during any of these calls.
I have not been able to figure out why the context is not retrieving the correct entity manager when in debugging mode.

Docusaurus v2 and GraphQL Playground integration

I'd like to render GraphQL Playground as a React component in one of my pages but it fails due to missing file-loader in webpack. Is there a way to fix this in docs or do I need to create new plugin with new webpack config?
Is it good idea to integrate Playground and Docusaurus at all?
Thanks for your ideas...
A few Docusaurus sites have embedded playgrounds:
Hermes
Uniforms
In your case you will have to write a plugin to extend the webpack config with file-loader.
Not sure if you found a better way but check out: https://www.npmjs.com/package/graphql-playground-react
You can embed this react component directly in your react app - It looks like Apollo also uses the vanilla JS version of this
I just had exactly the same problem. Basically, Docusaurus with a gQL Playground Integration runs fine in local but won't compile due to errors when running yarn build as above.
In the end I found the answer is in Docusaurus, not in building a custom compiler:
I switched from using graphql-react-playground to GraphiQL: package: "graphiql": "^1.8.7"
This moved my error on to a weird one with no references anywhere on the web (rare for me): "no valid fetcher implementation available"
I fixed the above by importing createGraphiQLFetcher from '#graphiql/create-fetcher' to my component
Then the error was around not being able to find a window component, this was an easy one, I followed docusaurus docs here: https://docusaurus.io/docs/docusaurus-core#browseronly and wrapped my component on this page in like this:
import BrowserOnly from '#docusaurus/BrowserOnly';
const Explorer = () => {
const { siteConfig } = useDocusaurusContext();
return (
<BrowserOnly fallback={Loading...}>
{() => {
const GraphEx = GraphExplorer
return
}}
);
}
This now works and builds successfully

Vuepress oidc-client preventing build

It looks like Vuepress is made for public docs, but we decided to add client and server security to protect some of the doc pages. But unfortunately although oidc-client (https://github.com/IdentityModel/oidc-client-js/wiki) works during dev, it throws exception when build.
I get ReferenceError: window is not defined and when I try to trick the compiler with const window = window || { location: {} }; I get TypeError: Cannot read property 'getItem' of undefined
Any idea how to make this work?
This was driving me nuts also. I discovered the component I was trying to add was looking at window.location in its code - this was triggering the error.
My understanding is that the build process has not access to Browser things like window etc.
As soon as I removed the window.location bit from my code things built just fine and all is well.

Using an Android library that extends AppCompatDialog

So I'm trying to create a plugin that uses PrettyDialog (https://github.com/mjn1369/PrettyDialog) using the latest NativeScript seed.
However I've run into the following error when compiling:
Error: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
That happens using the following code, and calling show() (TypeScript):
export class PrettyAlert {
show() {
const alert = this.createAlert();
}
createAlert(width?: number) {
return new libs.mjn.prettydialog.PrettyDialog(app.android.context);
}
}
I've been looking into the error here (pure Android): You need to use a Theme.AppCompat theme (or descendant) with this activity
But none of the solutions have worked.
I figure it possible somehow, but I'm new a plugin building, and I'm sure there's some quirks I need to understand.
There are similar plugins - fancyalert / cfalert already if you are not very choosy about PrettyDialog.
NativeScript introduced support for AppCompatActivity from v5.x which seems just hit live. You should bypass this error if you upgrade to latest version.

V8 "Platform" is null

I'm calling "Isolate->IdleNotification(100)" within an isolate scope (via "v8::Isolate::Scope ..."), and at some point when "V8::GetCurrentPlatform()->CallOnBackgroundThread(...)" is called within V8, "V8::GetCurrentPlatform()" returns NULL, and the whole thing dies a fatal death. Any ideas why the current platform might be null? Or rather, what should be done to make sure it isn't? Everything else seems to be working just fine.
Addition details: I'm using Visual Studio 2013, and compiled the source, the resulting libraries of which I use with the V8.Net wrapper (on codeplex). I run the following code before triggering the idle notification call:
v8::Locker __lockScope(engine->Isolate());
v8::Isolate::Scope __isolateScope(engine->Isolate());
v8::HandleScope __handleScope(Isolate::GetCurrent());
I tried different combinations, and it seems only v8::Locker __lockScope is required, but the platform is still null;
v8::Platform* V8::GetCurrentPlatform() {
DCHECK(platform_); // <-- 'platform_' is NULL
return platform_;
}
Got this working shortly after, but forgot to post the answer. Here it is: Google changed stuff (surprise! :/), and now you have to initialize a platform first. I did this and it all works again:
v8::V8::InitializePlatform(v8::platform::CreateDefaultPlatform());
// Sets the v8::Platform to use. This should be invoked before V8 is initialized.
v8::V8::InitializeICU();
// Initialize the ICU library bundled with V8. (if using the bundled ICU)
v8::V8::Initialize();
// Initialize V8.

Resources