I am learning Angular 11. I am following this code. My code is like below.
carousel.interface.ts
export interface Slide {
headline?: string;
src: string;
}
carousel.component.ts
import { Component, Input } from '#angular/core';
import { Slide } from './carousel.interface';
#Component({
selector : 'carousel',
templateUrl : './carousel.component.html',
styleUrls : ['./carousel.component.scss'],
})
export class CarouselComponent {
#Input() slides: Slide[];
currentSlide = 0;
constructor() { }
}
Are { Slide } and Slide[] same ? If same then why slides is not populating ?
I read this SO post. But I think issue of that post is different.
I am working with precompiled stylesheet (from SASS) and only need to toggle classes.
I have two elements that will be writing to an event. Based on the event being true/false I want to to toggle a class on my component.
Would this work:
import { LitElement, html } from 'lit-element'
/**
*
*
* #export
* #class MenuMainButton
* #extends {LitElement}
*/
export class MenuMainButton extends LitElement {
static get properties() {
return {
name: { type: String },
toggled: { type: String }
}
}
constructor() {
super()
this.name = 'Menu'
this.toggled = ''
this.addEventListener('toggle-main-menu', this.handleEvents)
}
render() {
return html`
<a #click=${this._onClick} class="menu-button wk-app-menu-button app-menu-open ${this.toggled} govuk-body"
>${this.name}</a
>
`
}
handleEvents(event) {
this.toggled = event.toggle ? 'hide-item' : ''
}
_onClick() {
const toggleMainMenu = new CustomEvent('toggle-main-menu', {
toggle: this.toggled === '' ? 1 : 0
})
this.dispatchEvent(toggleMainMenu)
}
}
window.customElements.define('main-menu-button', MenuMainButton)
One way to make styles dynamic is to add bindings to the class or style attributes in your template.
The lit-html library offers two directives, classMap and styleMap, to conveniently apply classes and styles in HTML templates.
Styles - LitElement
I am using ace-editor in my angular app as a JSON editor, ace editor has a feature to dynamically resize based on the data.
When I have data within 1.5k lines it works seamlessly post that the chrome browser get hang, noticed that the CPU utilization is also high
Can any help me to identify how can I resolve this issue or any work around?
If it is an styling issue can anyone suggest how to fit the editor?
Resize logic:
ngAfterViewChecked() {
this.codeEditor.setOptions({
maxLines: this.codeEditor.getSession().getScreenLength(),
autoScrollEditorIntoView: true
});
this.codeEditor.resize();
}
editor.ts:
import {
Component, ViewChild, ElementRef, Input, Output, EventEmitter,
OnChanges, SimpleChanges
} from '#angular/core';
import * as ace from 'ace-builds';
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-github';
const THEME = 'ace/theme/github';
const LANG = 'ace/mode/json';
export interface EditorChangeEventArgs {
newValue: any;
}
#Component({
selector: 'app-editor',
templateUrl: './editor.component.html',
styleUrls: ['./editor.component.css']
})
export class EditorComponent implements OnChanges {
#ViewChild('codeEditor') codeEditorElmRef: ElementRef;
private codeEditor: ace.Ace.Editor;
#Input() jsonObject;
#Input() readMode;
#Output() change = new EventEmitter();
data: any;
mode: any;
constructor() { }
ngOnChanges(changes: SimpleChanges) {
for (const properties of Object.keys(changes)) {
if (properties == 'jsonObject') {
const currentJSONObject = changes[properties];
if (currentJSONObject.currentValue && currentJSONObject.firstChange == false)
this.codeEditor.setValue(JSON.stringify(currentJSONObject.currentValue, null, '\t'), -1);
else if (currentJSONObject.currentValue == null && currentJSONObject.firstChange == false)
this.codeEditor.setValue("");
else
this.data = currentJSONObject.currentValue
}
if (properties == 'readMode') {
const currentReadMode = changes[properties];
if (currentReadMode.firstChange == false)
this.codeEditor.setReadOnly(currentReadMode.currentValue);
else
this.mode = currentReadMode.currentValue
}
}
}
ngAfterViewInit() {
const element = this.codeEditorElmRef.nativeElement;
const editorOptions: Partial<ace.Ace.EditorOptions> = {
highlightActiveLine: true,
displayIndentGuides: true,
highlightSelectedWord: true,
};
this.codeEditor = ace.edit(element, editorOptions);
this.codeEditor.setTheme(THEME);
this.codeEditor.getSession().setMode(LANG);
this.codeEditor.setShowFoldWidgets(true);
this.codeEditor.setHighlightActiveLine(true);
this.codeEditor.setShowPrintMargin(false);
if (this.data)
this.codeEditor.setValue(JSON.stringify(this.data, null, '\t'), -1);
this.codeEditor.setReadOnly(this.readMode);
if (this.mode)
this.codeEditor.setReadOnly(this.mode);
}
ngAfterViewChecked() {
this.codeEditor.setOptions({
maxLines: this.codeEditor.getSession().getScreenLength(),
autoScrollEditorIntoView: true
});
this.codeEditor.resize();
}
onChange(updatedJSON) {
this.change.emit({ newValue: updatedJSON });
}
}
editor.html:
<div ace-editor #codeEditor [autoUpdateContent]="true" [durationBeforeCallback]="1000" (textChanged)="onChange($event)"
(change)="onChange(codeEditor.value)" class="editor">
</div>
Editor CSS property:
.editor {
min-height: 750px;
width: 100%;
}
Using editor component across the application by simply adding following tag in HTML body
<app-editor [jsonObject]="data" [readMode]="readMode" (change)="onChange($event)"></app-editor>
I need to apply a styling to a toast that will be used when a particular function is called. How do I do that?
toast.service.ts
import { Injectable, OnInit } from '#angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
#Injectable()
export class ToastrService {
public toasterStatus: BehaviorSubject<Message>;
constructor() {
this.toasterStatus = new BehaviorSubject<Message>(null);
}
showToaster(type: string, content: string) {
const toasterObj: Message = { severity: type, detail: content };
this.toasterStatus.next(toasterObj);
}
}
export interface Message {
severity: String;
detail: String;
}
my-component.ts
import { ToastrService } from '../../../toast.service';
#Component({
selector: '...',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit, OnDestroy {
constructor(private logService: LogService,
private toastrService: ToastrService,){...}
ngOnInit() {
this.idSubscription$ = this.route.params.subscribe(params => {
this.id = +params['id'];
});
this.logService.debug(this.id);
// check for error
if (my.error) {
this.logService.error('Error retrieving report templates.', reportTemplatesState);
this.toastrService.showToaster('danger', 'Error retrieving report templates.');
}
});
//I need to apply the styling below to this toastrService element within the component method
my.component.css
.toastSticky{
position: -webkit-sticky; /* Safari */
position: sticky;
top: 0;
}
You do this with the documentation :
MatSnackBarConfig
Configuration used when opening a snack-bar.
panelClass: string | string[] Extra CSS classes to be
added to the snack bar container.
How I would check internet connection in Angular2 at the time of API hitting, whenever in my app API is hit to server sometimes user is
offline (i mean without internet connection) so how would i check the internet connectivity ? is there some special status code for internet connectivity ?
or something else ?
PS:- i found navigator.onLine in angularJs but seems not working in angular2.
Source - How to check internet connection in AngularJs
update
as sudheer suggested in answer below navigator.onLine in working with angular2 but still not working properly why ?
working example here
(2018) Code updated for rxjs6
It totally works with angular2. Obviously it's different from angularJS because neither $scope nor $apply exist anymore. RxJS makes this easy, though! Tested on Chrome 53:
template:
<p>{{online$ | async}}</p>
component:
import { Observable, fromEvent, merge, of } from 'rxjs';
import { mapTo } from 'rxjs/operators';
#Component({ /* ... */ })
export class MyComponent {
online$: Observable<boolean>;
constructor() {
this.online$ = merge(
of(navigator.onLine),
fromEvent(window, 'online').pipe(mapTo(true)),
fromEvent(window, 'offline').pipe(mapTo(false))
);
}
}
Think about what 'offline' means for your use case!
An unplugged ethernet cable and a 3KB/s EDGE connection likely have the same implications for your app although the latter means you're not technically offline!
From a programmer's point-of-view being connected wirelessly with a very poor signal is actually a lot worse than being truely disconnected because it's a lot harder to detect!
The above code returning a false value means your absolutely offline as in disconnected. It returning true doesn't necessarily indicate that there's a practically usable connection.
At first, j2L4e's answer didn't work for me (testing in Chrome). I tweaked slightly by surrounding my bool in brackets in the ngIf and this ended up working.
<md-icon class="connected" mdTooltip="No Connection" *ngIf="!(isConnected | async)">signal_wifi_off</md-icon>
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/Rx';
#Component({
selector: 'toolbar',
templateUrl: './toolbar.component.html',
styleUrls: ['./toolbar.component.css']
})
export class ToolbarComponent implements OnInit {
isConnected: Observable<boolean>;
constructor() {
this.isConnected = Observable.merge(
Observable.of(navigator.onLine),
Observable.fromEvent(window, 'online').map(() => true),
Observable.fromEvent(window, 'offline').map(() => false));
}
ngOnInit() {
}
}
As i have checked navigator is global object like window. You can use in in angular2 and it worked fine for me.
import {Component} from 'angular2/core';
#Component({
selector: 'my-app',
template:`
navigator.onLine
{{onlineFlag}}
`
})
export class AppComponent {
public onlineFlag =navigator.onLine;
}
Using Angular 6+ and Rxjs 6+, you can do it in the following way:
import { Observable, fromEvent, merge, of } from 'rxjs';
import { mapTo } from 'rxjs/operators';
online$: Observable<boolean>;
constructor() {
this.online$ = merge(
of(navigator.onLine),
fromEvent(window, 'online').pipe(mapTo(true)),
fromEvent(window, 'offline').pipe(mapTo(false))
)
}
Here is a demo (toggle network in dev tools)
Safe Approach to listen to network states
Answers given above works well but are not considered safe approach.
1.Browser dependent objects like window should not be referenced directly, always check for platform.
2.Furthermore functionality like Network Connection must be encapsulated into a service.
Below is the ConnectionService which can be subscribed to listen network states. It follows the rxjs 6 style.
Complete Code
import { Injectable, Inject, PLATFORM_ID } from '#angular/core';
import { Observable, fromEvent, merge, empty } from 'rxjs';
import { isPlatformBrowser } from '#angular/common';
import { mapTo } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class ConnectionService {
private connectionMonitor: Observable<boolean>;
constructor(#Inject(PLATFORM_ID) platform) {
if (isPlatformBrowser(platform)) {
const offline$ = fromEvent(window, 'offline').pipe(mapTo(false));
const online$ = fromEvent(window, 'online').pipe(mapTo(true));
this.connectionMonitor = merge(
offline$, online$
);
} else {
this.connectionMonitor = empty();
}
}
monitor(): Observable<boolean> {
return this.connectionMonitor;
}
}
in component, you may listen by subscribing to monitor() or directly into HTML using async pipe.
For Angular 9 - a very simple solution and comfortable using (thanks to this and this solutions):
1) Create new component:
ng g c NoConnection
no-connection.component.ts
import { Component, OnInit } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser'
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-no-connection',
templateUrl: './no-connection.component.html',
styleUrls: ['./no-connection.component.css']
})
export class NoConnectionComponent implements OnInit {
isConnectionAvailable: boolean = navigator.onLine;
constructor(private httpClient: HttpClient) {
window.addEventListener('online', () => {
this.isConnectionAvailable = true
});
window.addEventListener('offline', () => {
this.isConnectionAvailable = false
});
}
ngOnInit(): void {
}
}
no-connection.component.html (customise page as you want)
<div>
<p style.color = "{{ isConnectionAvailable ? 'green' : 'red'}}"> {{ isConnectionAvailable ? 'Online' : 'Offline'}} </p>
<!-- https://stackoverflow.com/questions/13350663/greyed-out-waiting-page-in-javascript#answer-13350908 -->
<div id="blackout" class="noselect" style.display = "{{isConnectionAvailable ? 'none' : 'block'}}">
<br><br><br><br><br>
<p>No Internet connection!</p>
<br>
</div>
</div>
no-connection.component.css
#blackout {
width:100%;
height:100%; /* make sure you have set parents to a height of 100% too*/
position: absolute;
left:0; top:0;
z-index:10; /*just to make sure its on top*/
opacity: 0.5;
background-color:#333;
text-align: center;
font-size:25px;
color: white;
}
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome, Opera and Firefox */
}
2) Use it anywhere you want - in my case the best place - is a root component:
app.component.html
<div>
<app-no-connection></app-no-connection>
<app-main></app-main>
</div>
Go with this simple Hack.
Working in angular 5 or later
constructor(){
setInterval(()=>{
if(navigator.onLine){
//here if it is online
}else{
//here if it is offline
}
}, 100)
}
write this in constructor of app.component.ts or your app bootstrap
No need of any external library ..
import { Injectable } from '#angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class InternetInterceptor implements HttpInterceptor {
constructor() { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// check to see if there's internet
if (!window.navigator.onLine) {
// if there is no internet, throw a HttpErrorResponse error
// since an error is thrown, the function will terminate here
return Observable.throw(new HttpErrorResponse({ error: 'Internet is required.' }));
} else {
// else return the normal request
return next.handle(request);
}
}
}
Use this.
Without any external library.
public isOnline: boolean = navigator.onLine;
ngOnInit() {
console.log(this.isOnline);
}