How to render multiple templates up to a condition in angular templateUrl - javascript

I need if is devise is mobile then render will be one HTML file and if is a desktop then render will be another HTML file. Below is my component file of code here that provide a JIT compilation error. Please help if have any effective ideas.
import { Component, OnInit, Output, EventEmitter, OnDestroy, Input, AfterViewInit, OnChanges } from '#angular/core';
import { ProductSearch, Supplier } from '../../product-models/inventory.models';
import { FORMAT_SEARCH } from '../../../../../globals/_classes/functions';
import { InventoryService } from '../../inventory-serveice/inventory.service';
import { Category } from '../../../settings/models/category.models';
import { ActivatedRoute } from '#angular/router';
import { Subscription } from 'rxjs';
import { CartService } from '../../../../cart-service/cart.service';
import { ProductListService } from '../product-service/product-list.service';
import { DeviceDetectorService } from 'ngx-device-detector';
console.log('window.isMobile !!!', window['isMobile']);
let VarTemp = '';
if(window['isMobile'] == true){
VarTemp = './product-search-test.component.html';
}else{
VarTemp = './product-search.component.html';
}
#Component({
selector: 'product-search',
templateUrl: VarTemp,
styleUrls: ['../product-list.component.css']
})

I would suggest to use the same template for both devices, then in this unique template add angular templates to manage displayment according current device.

Related

Cyclic Dependency in Angular 4 while Opening one modal component from another

In my app, I want to open a modal popup for user to upload a file. So I used below code for it (Used angular material to open the popup):
Actual service call happens after I upload document and if uploaded wrong document then service respond with error message.
What I want to achieve is If user select incorrect document I want to show another popup (Error Modal popup).
However when I import dialog.service.ts in uploaddoc.component.ts gives me below error
Can't resolve all parameters for UploaddocComponent
also throws warning in console saying :
WARNING in Circular dependency detected:
src\app\dialog.service.ts ->
src\app\uploaddoc\uploaddoc.component.ts ->
src\app\dialog-service.service.ts
WARNING in Circular dependency detected:
src\app\uploaddoc\uploaddoc.component.ts ->
src\app\dialog.service.ts ->
src\app\uploaddoc\uploaddoc.component.ts
Note : UploaddocComponent and ErrorModalComponents are both added in entryComponents array in app.module.ts as both are dynamic components.
Below is my code (and reproduced in stackblitz)
Main Component(to open upload popup ):
HTML
<button type="button" (click)="openUpload()">Open Upload Popup</button>
Component.ts
import { Component } from '#angular/core';
import { MatDialog } from '#angular/material';
import { DialogService } from './dialog.service';
import { ErrorModalComponent } from './error-modal/error-modal.component';
import { UploaddocComponent } from './uploaddoc/uploaddoc.component';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular 5';
constructor(public dialog: MatDialog,private dialogsService: DialogService){
}
public openUpload(){
this.dialogsService.openUploadDialog(UploaddocComponent);
}
}
My dialog.service.ts
import { Injectable } from '#angular/core';
import { ErrorModalComponent } from './error-modal/error-modal.component';
import { UploaddocComponent } from './uploaddoc/uploaddoc.component';
import { MatDialogRef, MatDialog, MatDialogConfig } from '#angular/material';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class DialogService {
constructor(private dialog: MatDialog) { }
public infoPopup(): Observable<boolean> {
let dialogRef: MatDialogRef<ErrorModalComponent>;
dialogRef = this.dialog.open(ErrorModalComponent);
dialogRef.componentInstance.data = "error";
return dialogRef.afterClosed();
}
public openUploadDialog(data: Object): Observable<boolean> {
let dialogRef: MatDialogRef<UploaddocComponent>;
dialogRef = this.dialog.open(UploaddocComponent);
dialogRef.componentInstance.data = data;
return dialogRef.afterClosed();
}
}
upload.component.ts
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { delay } from 'rxjs/operators';
import { of } from 'rxjs/observable/of';
import { DialogService } from '../dialog.service';
import { ErrorModalComponent } from '../error-modal/error-modal.component';
#Component({
selector: 'app-uploaddoc',
templateUrl: './uploaddoc.component.html',
styleUrls: ['./uploaddoc.component.css']
})
export class UploaddocComponent implements OnInit {
constructor(public dialogService: DialogService) { }
data: any;
ngOnInit() {
}
public uploadDoc() {
//in this method actual service call happens and check if correct document is uploaded or not.
// Service side sends error if wrong document is uploaded.
// If wrong doc is uploaded then I want to display Error component here
// I will simulate service call here with delay and will open ErrorModal
of(['some data']).pipe(
delay(2000)
).subscribe((res)=>{
console.log(res);
// suppose error occured here then I want to open error modal So I added `dialog.service.ts` here in this component
this.dialogService.infoPopup();
})
}
}
upload.component.html
<p>
Upload popup works
<button type="button" (click)="uploadDoc()">Do upload</button>
</p>
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { Components } from './materialComponents';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { DialogService } from './dialog.service';
import { UploaddocComponent } from './uploaddoc/uploaddoc.component';
import { ErrorModalComponent } from './error-modal/error-modal.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
#NgModule({
imports: [BrowserModule, FormsModule, ...Components,BrowserAnimationsModule],
declarations: [AppComponent, HelloComponent, UploaddocComponent, ErrorModalComponent],
bootstrap: [AppComponent],
entryComponents: [UploaddocComponent, ErrorModalComponent],
providers: [DialogService]
})
export class AppModule { }
I am not sure How should I handle circular dependency.
I may not have understood ngModule completely but guessing; Not able to inject service in components added in entryComponents array in app.module.ts.
What I am doing wrong here?
Well I tried below approach:
Modified uploaddoc.component.ts to :
import { Component, OnInit, Injector } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { delay } from 'rxjs/operators';
import { of } from 'rxjs/observable/of';
import { DialogService } from '../dialog.service';
import { ErrorModalComponent } from '../error-modal/error-modal.component';
#Component({
selector: 'app-uploaddoc',
templateUrl: './uploaddoc.component.html',
styleUrls: ['./uploaddoc.component.css']
})
export class UploaddocComponent implements OnInit {
constructor(private injector: Injector) {
this.dialogsService = this.injector.get(DialogsService);
}
data: any;
ngOnInit() {
}
public uploadDoc() {
of(['some data']).pipe(
delay(2000)
).subscribe((res)=>{
console.log(res);
// suppose error occured here then I want to open error modal So I added `dialog.service.ts` here in this component
this.dialogService.infoPopup();
})
}
}
I have used injector from #angular/core to explicitly get the service instance and no more error now.
however I can still see warnings. To remove warning I have added following in .angular-cli.json
"defaults": {
....
"build": {
"showCircularDependencies": false
}
}

Angular 2 Failed to compile

i created a new component in angular 2 with this:
ng g component todos
So it created the new component, I went to the component and I noted that I had a new folder with the files:
todos.component.css, todos.component.html, todos.component.spec.ts, todos.component.ts
Then I openened todos.component.ts and it had:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-todos',
templateUrl: './todos.component.html',
styleUrls: ['./todos.component.css']
})
export class TodosComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
Then I put the new second line because I am learning with a tutorial:
import { Component, OnInit } from '#angular/core';
import { TodosComponent } from './todos/todos.component';
#Component({
selector: 'app-todos',
templateUrl: './todos.component.html',
styleUrls: ['./todos.component.css']
})
export class TodosComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
When I did that and I ran the server it showed me this:
Failed to compile.
C:/angular2/proyecto/src/app/todos/todos.component.ts (2,10): Individual declarations in merged declaration 'TodosComponent' must be all exported or all local.
I'd like to know what is it bad? why does it show that error?
Thanks!
You are importing the class into it's own file.
No need to import your own component, you should import it in other files, where you use it.

Angular2 location.back() page reloads?

I am in need to give a Go-Back button for this I am using location services as:
import {Location} from '#angular/common';
backclicked(): void
{
console.log("back clicked.");
this.location.back();
}
<a id="redirect-link" (click)="backclicked();" style="padding:8px 15px;" >
Issue is this that location.back() is working but with page load. So is their a way where it can be achieved without page load ?. Any help please ?
You can use built in location service in angular 2 which having "Back" api.
import {Component} from '#angular/core';
import {Location} from '#angular/common';
#Component({ directives: [ROUTER_DIRECTIVES] })
#RouteConfig([
{...},
])
class AppCmp {
constructor(private _location: Location) {
}
backClicked() {
this._location.back();
}
}

How to import legacy js node_modules files in angular2 with webpack

I've a issue, I can't to import a BootstrapMenu in Angular2 with Bootstrap I met a difficulty when I want to import .js files with Webpack.
I get this error in my console :
Cannot find name 'BootstrapMenu'
I try to import BootStrapMenu like this :
import '../../../node_modules/bootstrap-menu/dist/BootstrapMenu.min.js';
This is my component :
import { Component } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import '../../../node_modules/bootstrap-menu/dist/BootstrapMenu.min.js';
console.log('`Dashboard` component loaded asynchronously');
#Component({
selector: 'dashboard',
templateUrl: 'dashboard.component.html'
})
export class Dashboard {
localState;
constructor(public route: ActivatedRoute) {
}
ngOnInit() {
this.route
.data
.subscribe((data: any) => {
this.localState = data.yourData;
});
console.log('hello `Dashboard` component');
var menu = new BootstrapMenu('.line', {
.....
.......
}
});
}
asyncDataWithWebpack() {
}
}
Thanks for your help

global service not working in angular2

I have created one global service in angular2 for accessing variables across all components like below.
global.objects.service.ts
import {Http} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import {Observer} from 'rxjs/Observer';
import 'rxjs/add/operator/share';
export class GlobalObjectsService {
workspace:any;
constructor() {
}
}
Then I am able to access & set new value to this object in my workspace.component like below:
import {Component, OnInit,Input} from 'angular2/core';
import { GlobalService} from './../../../app/shared/services/global/global.service';
import { GlobalObjectsService} from './../../shared/services/global/global.objects.service';
import { WorkspaceService } from './../../../app/shared/services/pm/workspaces.service';
#Component({
selector: 'workspaces',
providers:[WorkspaceService],
templateUrl: 'app/project-manager/workspaces/workspaces.component.html'
})
export class WorkspacesComponent implements OnInit {
#Input() workspaces:any;
constructor(private globalService:GlobalService,private globalObjectsService:GlobalObjectsService,private workspaceService:WorkspaceService) { }
ngOnInit() { }
selectWorkspace(workspace_id:string){
this.workspaceService.getWorkspaceById(workspace_id,this.globalService.baseUrl).subscribe((workspace)=>{
this.globalObjectsService.workspace=workspace;
console.log(this.globalObjectsService.workspace); //this prints workspace correctly
});
}
}
But when I am trying to access this global Object in below component its showing undefined
import {Component, OnInit ,Input} from 'angular2/core';
import { GlobalObjectsService} from './../../shared/services/global/global.objects.service';
#Component({
selector: 'pages',
templateUrl: 'app/project-manager/pages/pages.component.html'
})
export class PagesComponent implements OnInit {
#Input() pages:any;
public workspace:any;
constructor(private globalObjectsService:GlobalObjectsService) {
this.workspace=this.globalObjectsService.workspace;
console.log(this.workspace); //this is not working
}
ngOnInit() { }
}
I have not included global.objects.service in providers of any component except the root component while bootstrapping.
any suggestions?
Your service is missing the #Injectable() directive. Just add it like this:
import {Injectable} from 'angular/core';
import {Http} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import {Observer} from 'rxjs/Observer';
import 'rxjs/add/operator/share';
#Injectable()
export class GlobalObjectsService {
workspace:any;
constructor() {
}
}
Read more on dependency injection in Angular 2 here.
It seems what you are missing is to inject a WorkspaceService into GlobalObjectsService
#Injectable()
export class GlobalObjectsService {
constructor(public workspace:WorkspaceService) {
}
}
You need to provide WorkspaceService like GlobalObjectsService. A global GlobalObjectsService can't have a more local WorkspaceService injected depending on where you inject GlobalObjectsService

Categories