#StackBounty: #angular #angular-routing Angular application in a subfolder routing issue

Bounty: 50

It is a bit of weird situation but we have to structure the two angular app as below.

App1 being the main angular app situated at the root and other angular app is in a subfolder.

All is working well except for the routing in App2 since it is overridden by the routes config in
Main app.

I am able to use the command below to build/deploy and appears to be working for App2 (subfolder)

ng build --prod --base-href /subfolder/ --deploy-url /subfolder/

App1 is configured to have unknown routes redirected to a 404 page like below

{ path: '**', redirectTo: '/404' }

The issue with if I refresh the page on App2. it got redirected to the 404 page defined in App1.
eg. http://www.example.com/subfolder/route1

How can I tell angular in App1 to ignore anything under subfolder and use its own angular routes in App2?


Get this bounty!!!

#StackBounty: #angular #lazy-loading #codemirror Where do I put imports that would normally go in main.ts, when I am doing lazy module …

Bounty: 100

In my Angular app, I would like to use the library CodeMirror inside a Lazily Loaded module.

The trouble I am having is that the CodeMirror documentation tell me to

In your main.ts or at the root of your application, see documentation:

import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/markdown/markdown';

Import the base css file and your
theme

@import '~codemirror/lib/codemirror'; @import '~codemirror/theme/material';

However I would prefer this code NOT be imported throughout my app since it is only used by one lazy module.

What can I do so that this is imported correctly only when needed?


Get this bounty!!!

#StackBounty: #angular #webpack Angular / Webpack, How to ignore "Module not found: Error: Can't resolve 'web-worker'&…

Bounty: 50

I have come across the following issue, one of the software libraries I’m using has an optional dependency on ‘web-worker’. If the web-worker package is available it will use it, if it cannot find the web-worker package, it will use an alternative code path that does not use the web-worker package.

The problem I run into is that when trying to create an angular build, it will give the following error.

Module not found: Error: Can’t resolve ‘web-worker’ in ‘C:Gitdataprojectdevangularnode_moduleselkjslib’

If I check the main.js file from this package, almost the first thing it does is check if web-worker is available, if it’s not it will not try to load web-worker.

    var workerThreadsExist = false;
    try {
      require.resolve('web-worker');
      workerThreadsExist = true;
    } catch (e) {}

    // user requested a worker
    if (options.workerUrl) {
      if (workerThreadsExist) {
        var Worker = require('web-worker');
        optionsClone.workerFactory = function (url) {
          return new Worker(url);
        };
      } else {
        console.warn('Web worker requested but 'web-worker' package not installed. nConsider installing the package or pass your own 'workerFactory' to ELK's constructor.n... Falling back to non-web worker version.');
      }
    }

So even though the code flow will never require(‘web-worker’) when it’s not available, for some reason I still get the error when trying to build my application.

If I change

if (options.workerUrl)

into

if (false)

It still gives me the Module not found error, the only way to get rid of the error is to install the package or remove the

var Worker = require(‘web-worker’);

line.

How can I tell angular or webpack to ignore this 1 missing package?


Get this bounty!!!

#StackBounty: #angular #angular-routing #angular-router #angular-route-guards Route multiple modules to the same path

Bounty: 50

I’m trying to make a role based routing system where app-routing module has multiple modules routing to the same route.

Eg.

const routes: CustomRoutes = [
  { path: 'login', component: LoginFormComponent },
  {
    path: '',
    canActivate: [CanActivateRole],
    data: {
      roles: UserType.ClientRoleType
    }, 
    pathMatch: 'full',
    loadChildren: () => { return ClientModule; },
  },
  {
    path: '',
    canActivate: [CanActivateRole],
    data: {
      roles: UserType.DCRoleType
    }, 
    pathMatch: 'full',
    loadChildren: () => { return DcEmpModule; },
  },
];

The canActivateRole is reading from route.data.roles to figure out if it can route to the module in loadChildren.

Note: I have tried to use the matcher config to route to load seperate modules as shown in
this answer
or
this, however I couldn’t find a way to do it since I am using a service. If there is a way to use a service in the matcher that will work.

UPDATE 1:
Some have asked for the service that I am using to figure out what module to load so I’ve created an approximate of what the canActivate looks like.

@Injectable()
export class CanActivateRole implements CanActivate {
  constructor(private auth: AuthService, private router: Router) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): boolean {
    // If not logged in
    if (this.auth.notLoggedIn() || this.auth.UserType == null) {
      this.router.navigateByUrl('/login');
      return false;
    }

    let routeData = route.data as CustomRouteData;

    if (routeData.roles == undefined) {
      // Is authenticated but no roles specified so allowed through
      return true;
    } 
    else if (Array.isArray(routeData.roles)) {
      routeData.roles.forEach(allowedRole => {
        if (this.auth.allowParentPermission(allowedRole, this.auth.UserType)) {
          return true;
        }
        return false;
      });
    }
    else {
      if (this.auth.allowParentPermission(routeData.roles, this.auth.UserType)) {
        return true;
      }
    }

    return false;
  }
}

An alternative I tried to do was some sort of service that returned a module to load in loadChildren

@Injectable()
export class RouteMatcher {
  constructor(private auth: AuthService) {}

  /**
   * Used to match user roles to route to modules.
   *
   * To use return function in loadChildren key in routes eg.
   * ```
   * {
   *  path: '',
   *  loadChildren: () => return userRoleModuleMatcher(obj);
   * }
   * ```
   *
   * `Obj`: A map of which UserType or list of UserTypes will be matched onto a module. That module will route all of it's children to the original router. Eg.
   * `[[DCRoleType, EmpRoleType], EmpModule]`
   * will match both `DCRoleType` and `EmpRoleType` onto the `EmpModule`
   */
  public userRoleModuleMatcher(
    obj: ReadonlyMap<
      typeof UserType.UserType[] | typeof UserType.UserType,
      any
    >
  ): any {
    obj.forEach((module, allowedRoles) => {
        if (Array.isArray(allowedRoles)) {
            allowedRoles.forEach(role => {
              if (this.auth.allowParentPermission(role, this.auth.UserType)) {
                return module;
              }
            });
          }
          else {
            if (this.auth.allowParentPermission(allowedRoles, this.auth.UserType)) {
              return module;
          }
        }

        // If there are no matching permissions then route to shared module which has Server Error component
        return SharedModule;
    });
  }
}


Get this bounty!!!

#StackBounty: #angular #typescript #intro.js Why does Intro js element selection not work in mat card

Bounty: 50

I have created a tour, added step and ids to elements. But a element that is nested in, is an angular component or is from a library that is for angular will not be highlighted.

This is my tour:

this.introJS.setOptions({
      tooltipClass: 'customTooltip',
      highlightClass: 'customHighlight',
      exitOnOverlayClick: false,
      disableInteraction: false,
      steps: [
        {
          intro: 'Welcome to the web let me show you around!',
        },
        {
          element: '#step2',
          intro: 'Go to Home',
          position: 'right'
        },
        {
          element: document.getElementById('step3'),
          intro: 'Fill out the form',
          position: 'right'
        },
        {
          element: document.querySelector('#step4'),
          intro: 'Click Create an account',
          position: 'right'
        }
      ]
    }).start();

This is the html:

<div>
  <mat-card>
    <mat-card-content>
      <form id="step3" [formGroup]="testForm">
        <h3>test</h3>
          <mat-form-field appearance="outline">
            <mat-label>label</mat-label>
            <mat-select formControlName="role">
              <mat-option>1</mat-option>
            </mat-select>
          </mat-form-field>
      </form>
    </mat-card-content>
  </mat-card>
</div>

This is what the tip looks like:
enter image description here

It’s in the centre and doesn’t highlight anything

Edit:
If CyC0der’s answer is correct then I have problem with using the ngnIntroService. I can’t seem to get it included correctly. I created another question just for that issue here.


Get this bounty!!!

#StackBounty: #angular #navigation #state #ngrx #ngrx-store Dispatch action when navigating on the same page with NgRx Router Store

Bounty: 100

I am currently building an application using NgRx and the Router Store.
There is a dropdown in one component, that changes params in the url and navigates on the same component.
Since navigating on the same component doesn’t call NgOnInit the corresponding effect (that calls the API) is not called.
In my opinion, the effect should always be called if component has changed the params.

loadTransactions$ = createEffect(() => this.actions$.pipe(
  ofType(
    NavigationActions.ActionType.NavigateToTransactionsSuccess,
    TransactionsPageActions.ActionType.LoadPage
  ),
  [...]
));

One idea I had, was to create a custom action that only listens to navigations on the component with the dropdown, but i have no idea how to do this.

My current solution is following:

this.store.select(RouterSelectors.selectUrl).subscribe(() =>
  this.store.dispatch(TransactionsPageActions.loadPage())
);

But this feels like it could cause some bugs in the future.
Is there any way to achieve this in a clean way?


Get this bounty!!!

#StackBounty: #angular #yarnpkg #nrwl-nx #nrwl Project generator with specific ng/nrwl versions

Bounty: 50

Sadly we are, for several reasons, not able to use the angular 12 version, therefore we do not want to use the current versions of ng and nrwl.

I haven’t found documentation about how to generate a project with a specific version of ng. It seems that it always uses the most corrent version. But we need to use an older version (^10.0.0).

What I do is this:

yarn global add @nrwl/cli@10.0.6
yarn create nx-workspace myProject --style=scss --preset=empty --nx-cloud=false --cli=angular

But this will use the 12.6.5 version:

    "@angular/cli": "~12.1.0",
    "@nrwl/tao": "12.6.5",
    "@nrwl/cli": "12.6.5",
    "@nrwl/workspace": "12.6.5",
    "@types/node": "14.14.33",
    "dotenv": "~10.0.0",
    "ts-node": "~9.1.1",
    "typescript": "~4.3.5",
    "prettier": "^2.3.1"

I like to avoid all ^12 versions and get instead the ^10 versions of these libraries.

When I try (I am not sure if this is correct syntax): yarn create nx-workspace@10.0.6 myProject --style=scss --preset=empty --nx-cloud=false --cli=angular it does not succed.

I get an error, like:

success Installed "create-nx-workspace@10.0.6" with binaries:
      - create-nx-workspace
/bin/sh: /usr/local/bin/create-nx-workspace@10.0.6: No such file or directory
error Command failed.

If anybody could tell me how to execute a create nx-workspace command with a specific version, I would be thankfull.


Get this bounty!!!

#StackBounty: #angular #google-chrome #visual-studio-code #progressive-web-apps #vscode-debugger Unbound breakpoint – Angular, VS Code,…

Bounty: 50

Versions:

Angular CLI: 11.2.11
Node: 14.16.0
VS Code: 1.59.0
Chrome: 92.0.4515.131 
Debugger for Chrome (Nightly): v2020.2.15300
JavaScript Debugger (Nightly): v2021.8.217
(No other VS Code extensions loaded)

Environment

Windows 10 – Running as limited user. Not able to install anything but approved software, meaning, I’m stuck with the version of Node above, I can upgrade VS Code, but not install a specific version, etc.

launch.json:

    {
        "name": "Launch PWA-Chrome",
        "request": "launch",
        "type": "pwa-chrome",
        "url": "http://localhost:4200/",
        "webRoot": "${workspaceFolder}"
    },
    {
        "name": "Attach to Chrome",
        "port": 9222,
        "request": "attach",
        "type": "pwa-chrome",
        "webRoot": "${workspaceFolder}"
    }

Details:

  • Occurs for a vanilla Angular app configured as a PWA. Set a
    breakpoint anywhere and get "unbound breakpoint".
  • Occurs when
    launching Chrome and when attaching to Chrome (in debug mode).
  • Does not occur for non-PWA vanilla angular app – I can debug non-PWA vanilla angular app.

Research and what I’ve tried:

  • My situation is different than this: Unbound breakpoint – VS Code | Chrome | Angular . Mine is a PWA and I always have an unbound breakpoint when starting with "ng serve".
  • Tried change in angular.json: "sourceMap": true – No effect
  • Tried "Run -> Disable All Breakpoints, then Enable All Breakpoints" – No effect
  • Tried downgrading VS Code to 1.52.1 (when debugging last worked) – No effect
  • Tried adding to webpack: devtoolModuleFilenameTemplate: ‘[absolute-resource-path]’ – No effect
  • Tried disabling all extensions, except for Chrome and JS debugger – No effect
  • Tried attaching to Chrome in debug mode – still won’t hit a breakpoint


Get this bounty!!!