Multiple tabs with materialize next (V1)? - materialize

I cannot use multiple tabs in the same page while using materialize v1 and angular.
This is my app.component.ts:
`
/* import { Component } from '#angular/core'; */
import { Component, OnInit } from '#angular/core';
import 'materialize-css';
declare var M: any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
title = 'app';
ngOnInit() {
const instanceSidenav = new M.Sidenav(document.querySelector('.sidenav'));
const instanceTab = new M.Tabs(document.querySelector('.tabs'));
}
}
`
And the sidenav menu works and even the first tab in the page works, but the second one doesnt' work. I turned the first to be the second and the same ocurs with the new second tabs.
What can I do without jquery?

I found a way to make it work: Instead of initialize the tabs in the official documentation way that uses a class selector inside a document.querySelector('.tabs') , I used ids selectors in this way document.querySelector('#tab1').
This worked for me until I think the problem needs a better approach.

Related

Add "Remember me" checkbox to the login page

How to add to the Login Form new field like "Remember me". Which is not supported out-of-the-box?
Now login form provides just "email" and "password" fields, I extended form with new FormControl remember in ngOnInit method, but I can't pass received value to the auth.authorize method, because this method doesn't expect new value.
import { Component, OnInit } from '#angular/core';
import {FormBuilder, FormControl, Validators} from '#angular/forms';
import {ActivatedRoute} from '#angular/router';
import {AuthRedirectService, AuthService, GlobalMessageService, WindowRef} from '#spartacus/core';
import {CheckoutConfigService, LoginFormComponent} from '#spartacus/storefront';
#Component({
selector: 'app-app-login-form',
templateUrl: './app-login-form.component.html',
styleUrls: ['./app-login-form.component.scss']
})
export class AppLoginFormComponent extends LoginFormComponent implements OnInit {
constructor(
auth: AuthService,
globalMessageService: GlobalMessageService,
fb: FormBuilder,
authRedirectService: AuthRedirectService,
winRef: WindowRef,
activatedRoute: ActivatedRoute,
checkoutConfigService: CheckoutConfigService,
) {
super(auth, globalMessageService, fb, authRedirectService, winRef, activatedRoute, checkoutConfigService);
auth.authorize('email.email.com', '123', true);
}
ngOnInit(): void {
super.ngOnInit();
this.loginForm.addControl('remember', new FormControl('', Validators.required));
}
}
Environment:
Spartacus 3.0
Screenshot was given from Spartacus 2, but I'm sure you that is the same contract/problem for Spartacus 3.
Need to override AuthService and add internal variable and then read it.

Vue.js + Bootstrap - question - invoking $bvToast from store.js

I have probably very profoundly simple question: how to invoke methods located in components from store.js, for instance I want a toast popup from store mutation. Any ideas?
The $bvToast can be found in BToast export. You can import it to use it.
import { BToast } from 'bootstrap-vue'
Example Class
import { BToast } from 'bootstrap-vue'
class uiUtils
{
showToast(message : string,title : string){
let bootStrapToaster = new BToast();
bootStrapToaster.$bvToast.toast(message, {
title: title,
toaster: "b-toaster-top-right",
solid: true,
appendToast: false
})
}
}
export default new uiUtils();
The documentation does show the individual component exports at the bottom of the page and can be found here Bootstrap Vue Documentation.

Emit an event through service in Angular

What is the proper way of emitting an event through a service. I have read that declaring the EventEmmiter in the service it's not suitable.
I want to achieve the following.
I have 2 components inside the root component, when I click in the first component, I want to know that the first component was clicked in the second component.
There are four possible scenarios in which you can share your data but it depends upon your requirements
Parent to Child: Sharing Data via Input
Child to Parent: Sharing Data via ViewChild
Child to Parent: Sharing Data via Output() and EventEmitter
Unrelated Components: Sharing Data with a Service
When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should you a shared service. When you have data that should aways been in sync, I find the RxJS BehaviorSubject very useful in this situation.
You can also use a regular RxJS Subject for sharing data via the service, but here’s why I prefer a BehaviorSubject.
It will always return the current value on subscription - there is no need to call onnext
It has a getValue() function to extract the last value as raw data.
It ensures that the component always receives the most recent data.
In the service, we create a private BehaviorSubject that will hold the current value of the message. We define a currentMessage variable handle this data stream as an observable that will be used by the components. Lastly, we create function that calls next on the BehaviorSubject to change its value.
The parent, child, and sibling components all receive the same treatment. We inject the DataService in the constructor, then subscribe to the currentMessage observable and set its value equal to the message variable.
Now if we create a function in any one of these components that changes the value of the message. when this function is executed the new data it’s automatically broadcast to all other components.
Here its a code snippet.
data.service.ts
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class DataService {
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
parent.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-parent',
template: `
{{message}}
`,
styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
}
second.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-sibling',
template: `
{{message}}
<button (click)="newMessage()">New Message</button>
`,
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
newMessage() {
this.data.changeMessage("Hello from Sibling")
}
}
I used Replaysubject to notify about changes in data that needed to be updated to the gui in gui-component when the data provided by the service changes.
A service makes a ReplaySubject which holds the data that may change.
All the gui-components / other services subscribe to this object in their init function and get later notified about changes in data. => Do what they need to do.
In my case the service has a polling interval and the data held by it may change without any user actions.

Angular2 ng-book-2 simple sample chapter 1 app , it works fine in the browser , but why do I get this error?

On Mac OS X El Capitan, I follow all the steps from Page 1 to page 18 of this simple app, but at the screen where I run "ng serve" I get this error:
ERROR in [default]
/Users/bob/angular2_hello_world/src/app/user-item/user-item.component.ts:11:8
Property 'name' does not exist on type 'UserItemComponent'.
From Page 1 :
Writing your First Angular 2 Web Application
Simple Reddit Clone
TO
Page 18:
Try it out
"After making these changes reload the page and the page should display Hello Felipe""
The error is that you use a "name" variable inside the component template but it's not defined inside the component. Define and use it like this in your component:
import { Component } from '#angular/core';
#Component({
selector: 'app-user-item-component',
template: `
<h1>{{name}}</h1>
`,
styles: []
})
export class AppComponent {
name: string = "Hello Felipe"
}
I had the same problem, just reading ng-book2-r49, you need to define that name property in class as names: string[]; so it looks like this
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-user-item',
templateUrl: './user-item.component.html',
styleUrls: ['./user-item.component.css']
})
export class UserItemComponent implements OnInit {
name: string;
constructor() {
this.name = 'Felipe'; // set the name
}
ngOnInit() {
}
}

angular 2 testing componnet with directives and got error router loading

everyone. I try to test angular 2 application and got some interesting error when I try to test component with directives (and in those directive-components - router is included). Got error from Karma:
Error loading http://localhost:9876/angular2/router as "angular2/router" from D:built/application/breadcrumbs/breadcrumbs.component.js .
I don`t know what to do with this issue. Can anybody help me please?
There is my header component test (via jasmine and Karma):
import { beforeEach,
beforeEachProviders,
describe,
expect,
it,
inject,
injectAsync} from 'angular2/testing';
import {HeaderComponent} from './header.component';
import {BreadcrumbsComponent} from '../../breadcrumbs/breadcrumbs.component';
describe('HeaderComponent Tests', () => {
//let HeaderComponent: HeaderComponent;
beforeEachProviders(() => [HeaderComponent,
BreadcrumbsComponent,
ROUTER_PROVIDERS]);
it('Should contains title property - "Header"', inject([HeaderComponent],
(headerComponent: HeaderComponent) => {
expect(headerComponent.title).toBe('Header');
}));
});
There is header component that I try to test.
import {Component} from 'angular2/core';
import {HeaderDataInterface} from './header.component.interfaces';
import {BreadcrumbsComponent} from '../../breadcrumbs/breadcrumbs.component';
import {SearchComponent} from '../../../modules/search/search.component';
// module path. Created for avoid copy/paste
const BUILT_MODULE_PATH: string = '/built/application/partials/header/';
#Component({
selector: 'cgm_header',
templateUrl: `${BUILT_MODULE_PATH}header.component.html`,
directives: [BreadcrumbsComponent, SearchComponent],
styleUrls: [`..${BUILT_MODULE_PATH}header.component.css`],
})
export class HeaderComponent {
public title: string = 'Header';
// contains header data
public headerData: HeaderDataInterface = {
'searchPlaceholder': 'Search for Patient Name, MRN or MPID...',
'logOutLabel': 'Log out'
};
}
There is breadcrumb component
import {ROUTER_DIRECTIVES, Router} from 'angular2/router';
const builtModulePath: string = '/built/application/breadcrumbs/';
#Component({
selector: 'sgm_breadcrumbs',
templateUrl: `${builtModulePath}breadcrumbs.component.html`,
styleUrls: [`..${builtModulePath}breadcrumbs.component.css`],
directives: [ROUTER_DIRECTIVES]
})
export class BreadcrumbsComponent implements OnInit {
private staticData = {
'title': 'Breadcrumbs',
'homeName': 'Home',
'dashboardName': 'Dashboard'
}
constructor(private _router: Router, private _injector: Injector) { }
}
ngOnInit() {
this._router.subscribe((value) => {
let instructions = [];
//console.log(this._router);
this._router.recognize(value).then(instruction => {
this.handleRouterRecognize(instruction);
});
update
<script src="https://code.angularjs.org/2.0.0-beta.14/router.dev.js"></script>
is missing in index.html Plunker example
original
Try without templateUrl (use template instead). There were some related issues especially with async tests.
To set up tests use
// Somewhere in the test setup
import {setBaseTestProviders} from 'angular2/testing';
import {
TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS
} from 'angular2/platform/testing/browser';
setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS);
See also https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta2-2016-01-28