How to load default Component in default App and next to do redirect to another sub app? - single-spa

I Have 3 apps : root-config (single-spa), navbar-app ( port 4201 angular 12 ) angular-app (port 4202 angular 12 )
My root-config app (localhost:9000) has root-config.ts
registerApplication({
name: "#org1/myNavbarApp",
app: () => System.import("#org1/myNavbarApp"),
activeWhen: ["/"],
});
registerApplication({
name: "#org1/myAngularApp",
app: () => System.import("#org1/myAngularApp"),
activeWhen: ['/angular']
});
my myNavbarApp has app-routing.module.ts
const routes: Routes = [
{
path: 'login', component: LoginComponent,
}, {
path: 'menu',
component: MenuComponent,
},
{path: '**', component: EmptyRouteComponent}, // <-- will display angular app but will not
leave <mat-toolbar> in view from myNavBarApp ( only if i stay in localhost:4200/menu
and do refresh -> angular app default view displays under <mat-toolbar> of
myNavBarApp ( as expected behavior )
// {path: '**', redirectTo: 'login'}, // <-- renders default "login.component" on first load
of localhost:9000 (exactly what i need) but will cause next issue:
after navigateToUrl('angular') is done - ```login.component``` angular app content
are visible in the same page - ( not expected behavior )
];
const config: ExtraOptions = {
useHash: false,
enableTracing: false,
relativeLinkResolution: 'legacy',
};
#NgModule({
imports: [RouterModule.forRoot(routes, config)],
exports: [RouterModule],
providers: [{provide: APP_BASE_HREF, useValue: '/'}]
})
export class AppRoutingModule {
}
NavBarApp has menu.component.html includes next:
<mat-toolbar color="warn" class="toolbar">
<mat-button-toggle-group class="menu">
<mat-button-toggle (click)="singleSpaNavigateUrl('angular')" value="angular">Angular App</mat-button-toggle>
</mat-button-toggle-group>
</mat-toolbar>
and menu.component.ts includes next :
import {getAppNames, navigateToUrl, getMountedApps} from "single-spa";
public singleSpaNavigateUrl(url: string) {
console.log('appNames', getAppNames()); <-- IS ALWAYS EMPTY ARRAY , Why ?
console.log('mountedAppNames', getMountedApps()); <-- IS ALWAYS EMPTY ARRAY , Why ?
navigateToUrl('/'+ url); // <-- navigates to /angular
}
How to achieve myNavBarApp menu.component will stay visible in all child apps after login / or when is needed ?
How to achieve login.component as default , when myNavBarApp is loaded from root-config app in browser ( without entering "/login" manually after that)
Single spa documentation says: single-spa Layout Engine is optional at this time but is recommended if you foresee utilizing server side rendering .. So i do not have server rendering ...thats why i do not implement layouts , and want to know how it possible to do without it ?
Why getAppNames() and getMountedApps() returns always empty array ?

Related

What is the right way to define child routes in Spartacus?

I am working in a B2B Spartacus project and we are currently implementing the MyCompany User/Unit management. The Spartacus implementation is a little to complex for our use-case so we are developing a custom solution based on it.
The original implementation features a CMS-Page for users (e.g.: https://spartacus-demo.eastus.cloudapp.azure.com:444/powertools-spa/en/USD/organization/users) and then Angular child routes for the user details (e.g.: /organization/users/7a95e933-364c-4c8d-81cd-4f290df0faf1)
I tried to replicate the child route implementation following the Spartacus documentation.
I created a parent (RightsManagementUser) and child (RightsManagementUserDetails) component.
<p>rights-management-user works!</p>
<a
class="btn btn-primary"
[routerLink]="{
cxRoute: 'orgUserDetails',
params: { customerId: '9e26d9fb-14eb-4ec6-9697-3fa53302245c' }
} | cxUrl"
>Go to User Details</a
>
<router-outlet></router-outlet>
Following the Spartacus Documentation, I provided a Spartacus and an Angular routing config
export const userRoutingConfig: RoutingConfig = {
routing: {
routes: {
orgUser: {
paths: ['organization/users'],
},
orgUserDetails: {
paths: ['organization/users/:userCode'],
paramsMapping: {
userCode: 'customerId',
},
},
},
},
};
RouterModule.forChild([
{
path: null,
component: PageLayoutComponent,
canActivate: [CmsPageGuard],
data: { cxRoute: 'orgUser' },
children: [
{
path: null,
component: RightsManagementUserDetailsComponent,
data: { cxRoute: 'orgUserDetails' }
},
],
},
]),
I also tried following the documentation for Adding Angular Child Routes for a Content Page
and added the child route to the cms config.
RightsManagementUserComponent: {
component: RightsManagementUserComponent,
childRoutes: [
{
path: ':userCode',
component: RightsManagementUserDetailsComponent,
},
],
},
This all wasn't enough, when clicking the button, the CMSPageGuard tries to load the CMS page for /organization/users/7a95e933-364c-4c8d-81cd-4f290df0faf1 instead of activating the child route.
I then tried to go the Angular way and defined the child route without using cxRoute:
children: [
{
path: ':userCode',
component: PflRightsManagementUserDetailsComponent,
},
],
At first I was happy, since the child route actually activated:
But then I realized that when I do a browser refresh Spartacus again tries to access the CMS-Page instead of activating the route.
Can someone please help me out and point me to the right way to use child routes in Spartacus?
If you would like to use split view, you can define your route in this way #customizing-routes, then clone whole cms configuration for organization feature and personalize childs #customizing-cms-components.
It could looks like:
const yourConfig = { ...userCmsConfig.cmsComponents.ManageUsersListComponent };
(yourConfig.childRoutes as CmsComponentChildRoutesConfig).children[1].component = RightsManagementUserDetailsComponent;
and include in your module
imports: [
// ...
B2bStorefrontModule.withConfig({
// ...
cmsComponents: {
ManageUsersListComponent: yourConfig,
},
},
// ...

I can't redirect ionic page using tab forms

I can't redirect a ionic 4 tab page to other tab page using parameters.
I'm using tabs-routing.module.ts with this code:
{
path: 'tab2/:id',
outlet: 'tab3',
children: [
{
path: '',
loadChildren: () =>
import('../tab2/tab2.module').then(m => m.Tab2PageModule)
}
]
},
/* {
path: 'tab2/:id',
outlet:'tab3',
component: Tab2PageModule
}, */
The view contains:
ion-button size="small" href="/tabs/tab2/{{f}}/"...
or
ion-button size="small" href="/tab2/{{f}}/" ...
The browser says:
core.js:9110 ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'tabs/tab2/1/'
When I use:
ion-button size="small" href="/tabs/(tab3:tab2/{{ f }})" ...
The url in browser is
http://localhost:8100/tabs/(tab3:tab2/2)
The content in the browser disappears and only shows the tabs.
To navigate within your app you should use routerLink directive like the following:
<ion-button size="small" [routerLink]="['/tabs/tab2/', id]">
routerLink directive documentation
It seems there is an other issue. Your declared routes are: tab2/:id and tab2/:id. Yet you're routing to /tabs/tab2/1 while you should be routing to /tab2/1
Like this:
<ion-button size="small" [routerLink]="['/tab2/', id]">
Thanks for your help, now it works correctly. However, now the controller does not get the parameter correctly.
In this screen I will call the details module
main module
But the module that receives the parameters does not get the data sent
This is how the screen looks without parameters
second module
When I add the complete code (using the parameter)
ion-button size=small routerLink=/tabs/tab2/{{f}}
ERROR Error: Uncaught (in promise): Error: Cannot match any routes.
URL Segment: 'tabs/tab2/3' Error: Cannot match any routes. URL
Segment: 'tabs/tab2/3'
The content of file tabs.routing.module.ts is
{
path: 'tab2/:id',
outlet: 'tab3',
children: [
{
path: '',
loadChildren: () =>
import('../tab2/tab2.module').then(m => m.Tab2PageModule)
}
]
},
{
path: 'tab2/:id',
outlet: 'tab3',
component: Tab2PageModule
},
the content of file tabs2.page.ts is
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { ListadoPokemonService } from '../servicio/listado-pokemon.service';
#Component({
selector: 'app-tab2',
templateUrl: 'tab2.page.html',
styleUrls: ['tab2.page.scss']
})
export class Tab2Page implements OnInit{
idPokemon: string;
nombrePokemon: string;
listado:any;
constructor(private activatedroute: ActivatedRoute, private servicio: ListadoPokemonService) { }
ionViewVillEnter(){
this.idPokemon = this.activatedroute.snapshot.paramMap.get('id');
// this.nombrePokemon = this.activatedroute.snapshot.paramMap.get('nombre');
this.servicio.getData('https://pokeapi.co/api/v2/pokemon/'+this.idPokemon+'/').subscribe(data=>{
console.log(data);
this.listado=data;
});
}
ngOnInit() {
}
}
Thanks in advance for your help i'm php & visual studio developer but new in angular & ionic issues.
I could solve it, just add the following code
{
path: 'tab2/:id',
//component: Tab2PageModule
loadChildren: () =>
import('../tab2/tab2.module').then(m => m.Tab2PageModule)
},
in tabs-routing.module.ts
I solved this problem by placing the redirect object above the empty path. like this example:
const routes: Routes = [
{
path: '',
redirectTo: '/user/profile-u',
pathMatch: 'full'
},
{
path: '',
component: UserPage,
children: [
{
path: 'job-applying',
loadChildren: () => import('./job-applying/job-applying.module').then(m => m.JobApplyingPageModule)
}, ...
I hope this helps you. I realize this seems like a trivial solution, but some things in this framework are just a little finicky.

Troubleshooting ionic 4 angular router navigation

so we're attempting to move our project from Ionic 3 to Ionic 4. To begin we started a basic tabs app: ionic start myApp tabs
I made two pages:
ionic generate page userList
ionic generate page userDetailed
I want two different tabs to have the ability to navigate to "UserListPage".
So I added it to the "tab1" & "tab2" router children:
tabs.router.module.ts
{
path: 'tab1',
children: [
{
path: '',
loadChildren: '../tab1/tab1.module#Tab1PageModule'
},
{
path: 'user-list',
loadChildren: './user-list/user-list.module#UserListPageModule'
}
]
}
Now I want the UserListPage to be able to navigate to the "UserDetailedPage".
I tried adding user-detailed as a path onto the UserListPageModule like so:
user-list.module.ts
const routes: Routes = [
{
path: '',
component: UserListPage,
children: [
{
path: 'user-detailed',
loadChildren: '../user-detailed/user-detailed.module#UserDetailedPageModule'
}
]
}
];
Now when I'm on tab1 & click a button to go to the list page, it works.
However when I click a button to go from list page to the detailed page, it changes the URL but does not display the page.
Any ideas what I'm doing wrong?
Your detailed page will be "user-list/user-detailed", your subroutes like user-detailed will be appended to the current route of user-list.

Vue: redirect to straight to child, while parent has a param

I'm learning Vue (on TS) and it seems awesome till this point. At the moment I learn about Vue routing, and have a question which I struggle to find a beautiful answer to.
Let's say, I have a parent route, named User, which gets userId as a param. I also have subpages for this route, which are called Profile and Settings respectively, and are being set in the User's children array:
routes: [
{
component: User,
name: 'User'
path: '/user/:userId',
children: [
{
component: Profile,
name: 'Profile',
path: 'profile',
},
{
component: Settings,
path: 'settings',
name: 'Settings'
},
],
}
]
It's pretty cool that I can redirect from User component to Profile or Settings as simple as
public redirectToProfile() {
this.$router.push({ name: 'Profile'});
}
But my question is - may I redirect to user's profile from outside of the User component the same way, without concatenating the path string like
public redirectToProfile() {
this.$router.push({ path: 'user/' + userId + '/profile'});
}
?
I think you can simply do it by passing params as well:
public redirectToProfile(id: string) {
this.$router.push({ name: 'Profile', params: {userId:id}});
}

ionic nav push params not shown in url

app.module.ts:
imports: [
IonicModule.forRoot(MyApp, {}, {
links: [
{ component: CategoryPage, name: 'Category', segment: 'category:id'}
]
}
],
providers: [
{
provide: LocationStrategy,
useClass: PathLocationStrategy
}
]
Configuration of the page I am navigating too
#IonicPage({
name: 'Category',
segment: 'category/:id'
})
Code which triggers navigation:
this.nav.push(CategoryPage, {id: 3});
The component does load as expected and I can call this.navParams.get('id') which yields 3 from within the components class.
Expected result: The url changes to /category:3
Observed result: The url changes to /category:id
so if you are trying to implement deep links for Ionic 3 (since Ionic 4 is using Angular's router by default now) you need to ensure you also configure each page accordingly.
The page you are navigating to needs to have configs added via #IonicPage:
#IonicPage({
segment: 'second/:id'
})
See more in ionic docs or this guide