app.component in angular 2 is mandatory to be staring component? - visual-studio

Currently I am using Visual studio for angular application with online Angular 2 template. The application is working fine when I choose default template and app.component as starting component. but when i need to change it with another component as starting component(home.component) my application not working.
Please guide me.

This is what you app module will be like now
#NgModule({
declarations: [
AppComponent // change this to HomeComponent
],
imports: [
BrowserModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent] // change this to HomeComponent
})
If you want to change the AppComponent to a different component just change the bootstrap array and declarations array to HomeComponent.
And if you you want to route use the RouterModule in importsto route from app to home component.

Related

Multiple Tailwind CSS Configs

I am building a project using Laravel/Inertia/Vue and I am using Tailwind CSS.
I want to have separate admin.css and client.css files using tailwindcss 3.2 ability to have multiple config files:
./styles/admin.css
#config "./tailwind.admin.config.js"
#tailwind base;
#tailwind components;
#tailwind utilities;
but the problem is that Vite will build just app.css for me not the admin one
vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
ssr: 'resources/js/ssr.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
ssr: {
noExternal: ['#inertiajs/server'],
},
server: {
host: "localhost",
},
});
app.css is imported in app.js
I can not figure it out
Could you please help me?
I want to have separate admin.css and client.css files per each tailwindcss config file.
You can pass an array of input files to vite as follows:
input: ['resources/js/app.js','resources/css/admin.css','resources/css/client.css']
This should result in seperate output files in your build directory.
If you want to keep the css as javascript import you can create a second InertiaApp for the admin area:
Copy app.js and rename it like 'admin.js'
Change css import in admin.js to '/styles/admin.css'
Change your vite input to: input: ['resources/js/app.js','resources/js/admin.js']
Use a different blade layouts for the 'admin' area with reference to admin.js instead of app.js : #vite('resources/js/admin.js')
Thanks #dustin for your answer. Here are some more things:
I can split javascript application by defining multiple rootViews using inertia-laravel#0.3.2 in HandleInertiaRequests.php middleware:
public function rootView(Request $request)
{
if ($request->routeIs('admin.*')) {
return 'admin';
}
return 'app';
}
And have two different apps.
But do you think its a good approach to have two different apps?
I like the separation idea but is it the right way?
I Also have concerns about bundling and mixing in inertia and ssr, would it be a problem for that when you have two apps? I dont know anything about inertia's way of working
I was hoping there is some other method like creating a higher order component or something like that. I am very new to Vue world and I am still trying to learn.

Angularfire conditionally provide appcheck

I have two angular projects:
Main app
Webcomponent (angular elements)
Webcomponent is used in the main app. Both are using angularfire for executing Firebase functions, working with Firestore and more.
Also I am enforcing verified request to the Functions and Firestore by AppCheck.
The web component needs to work separately. To be able to request Firebase servers I need to provide the AppCheck in both projects like this:
#NgModule({
...
imports: [
...
provideAppCheck(() => initializeAppCheck(getApp(), {
provider: new ReCaptchaV3Provider(environment.firebase.appCheck.recaptcha3SiteKey),
isTokenAutoRefreshEnabled: environment.firebase.appCheck.isTokenAutoRefreshEnabled,
}))
...
],
...
})
This works just fine when webcomponent is not included in the main app. However when so, the AppCheck is initialized two times and it throws an error:
Unhandled Promise rejection: reCAPTCHA has already been rendered in this element ; Zone: <root> ; Task: Promise.then ; Value: Error: reCAPTCHA has already been rendered in this element
So the webcomponent needs to check if appcheck already exists in document and add it only if it does not. I tried to work with appCheckInstance$ but that is an observable and provideAppCheck requires only AppCheck type.
When I try to move provideAppCheck to component which would handle the logic, I get an error saying that calling it can not be done outside module:
Either AngularFireModule has not been provided in your AppModule (this can be done manually or implictly using
provideFirebaseApp) or you're calling an AngularFire method outside of an NgModule (which is not supported).
I have no other ideas how this could be done other than building two webcomponents (one with appcheck, other without), but thats just not an option.
It turned out that the problem was elsewhere. I thought that conditional appcheck loading would help, but it didn't, because then angularfire(in webcomponent) didn't use the appcheck that the main app initialized. And hence connections to firebase were blocked (as if there was no appcheck initialized).
Solution I've figured out that works:
In webcomponent initialize all firebase services under different name.
So instead of:
#NgModule({
...
imports: [
...
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => getFirestore(getApp())),
provideAppCheck(() => initializeAppCheck(getApp(), {
provider: new ReCaptchaV3Provider(environment.firebase.appCheck.recaptcha3SiteKey),
isTokenAutoRefreshEnabled: environment.firebase.appCheck.isTokenAutoRefreshEnabled,
})),
...
],
...
})
do:
#NgModule({
...
imports: [
...
provideFirebaseApp(() => initializeApp(environment.firebase, 'webcomponent-app')),
provideFirestore(() => getFirestore(getApp('webcomponent-app'))),
provideAppCheck(() => initializeAppCheck(getApp('webcomponent-app'), {
provider: new ReCaptchaV3Provider(environment.firebase.appCheck.recaptcha3SiteKey),
isTokenAutoRefreshEnabled: environment.firebase.appCheck.isTokenAutoRefreshEnabled,
})),
...
],
...
})
This will initialize two instances (one for main app, other for webcomponent) with different names. And now initializing two appchecks is not problematic.

Using Router for web and RouterExtensions for mobile in a single component

I am trying to code share in my project between a web and mobile app version.
I have a component that requires programmatic navigation and therefore I need to inject the Angular Router (from '#angular/router') for the web version and NativeScript RouterExtensions (from '#nativescript/angular') for the mobile version. Is there a recommended way to "dynamically" inject a dependency into a component, so that each target that is compiled for gets the correct dependency?
At the first step you should create an injection token
// src/app/tokens.ts
import {InjectionToken} from '#angular/core';
export const UNIVERSAL_ROUTER = new InjectionToken<string>('Custom router');
After that in your module which is related to web application (I assume it is app.module.ts) you define it in your providers list
// src/app/app.module.ts
...
import {Router, RouterModule} from '#angular/router';
import {UNIVERSAL_ROUTER} from '~/app/tokens';
#NgModule({
imports: [...],
declarations: [...],
providers: [
{provide: UNIVERSAL_ROUTER, useExisting: Router},
],
bootstrap: [AppComponent],
})
export class AppModule {}
Simultaneously you define this token as a RouterExtension in the module which states for mobile application (i.e. app.module.tns.ts):
// src/app/app.module.tns.ts
...
import {NativeScriptRouterModule, RouterExtensions} from 'nativescript-angular/router';
import {UNIVERSAL_ROUTER} from '~/app/tokens';
#NgModule({
imports: [...],
declarations: [...],
providers: [
{provide: UNIVERSAL_ROUTER, useClass: RouterExtensions},
],
bootstrap: [AppComponent],
schemas: [NO_ERRORS_SCHEMA],
})
export class AppModule {}
Having this done, you can inject router by means of #Inject decorator like
constructor(#Inject(UNIVERSAL_ROUTER) private router) {}
and get a platform-specific router wherever you need it.

Can't resolve all parameters for UIRouter: (?, ?)

I am using angular2 and uirouter for routing. I have successfully implemented uirouter module in application.But the problem arises when i try to test my application. Where i am using karma, Jasmin and initiating it using npm test. but encountered with ERROR:Can't resolve all parameters for UIRouter: (?, ?).
I have imported "UIRouter" in *.spec.ts file and added it in providers array as below.
import { UIRouterModule } from '#uirouter/angular';
import { UIRouter } from "#uirouter/core";
describe('Footer Menus', () => {
let footerMenuBlServiceRef:FooterMenuBLService;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [],
providers: [UIRouter],
})
.compileComponents();
}));
But no luck. Any help will be appreciated.
Solved it !!!
Just remove the UIRouter from providers array but keep the import statement for it. and yes its working.
On last friday, I finally found a way to make it work. It is not a clean way to do it but it is working, at least.
I reimport the UIRouter.forRoot with the states of my feature module and I provide the APP_BASE_HREF value for the Root Provider of UIRouter.
Here is my BeforeEach :
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
HomeComponent,
HomeCardComponent
],
imports: [
AppMaterialModule,
// Always import root UIRouter module when testing a component including routing
UIRouterModule.forRoot({states: HOME_STATES})
],
providers: [
// Also, include the base href value when testing a component including routing
{provide: APP_BASE_HREF, useValue: '/'}
],
}).compileComponents();
}));
If you know a better way, I would be happy to know! :)
The UI-Router source can be of some help. This is what worked for me:
import { UIRouterModule } from '#uirouter/angular';
...
TestBed.configureTestingModule({
...
imports: [UIRouterModule.forRoot({ useHash: true })],
})

ionic 3 navigation transition with push other pages

I want to make animation transition in my ionic 3 app when navigate to page.
I'm using this documentation
I declared in my app.module.ts
#NgModule({
declarations: [
MyApp,
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp,{
PageTransition: 'wp-transition'
}),
AngularFireModule.initializeApp(FIREBASE_CONFIG)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
})
export class AppModule {}
then when I navigate to page I wrote this
NavigateToPage(pageName: string){
let opts = { animate: true, animation: "wp-transition",direction:'forward', duration: 2500}
pageName === 'TabsPage'? this.navCtrl.setRoot(pageName,opts) : this.navCtrl.push(pageName,opts);
}
}
but I don't see any transition, it looks the same as before.
any idea?
I've made it work(a push()) in one of my project by doing this:
this.navCtrl.push(pageName,{/*here stay navParams - but for this example is empty, but still need to use {}*/},opts);
So without the comment: this.navCtrl.push(pageName,{},opts);

Resources