I am trying to use formControlName inside a Kendo Text Area, and have a outer component apply it.
Using the following code base link, its still not working.
Angular 2 - formControlName inside component
How would someone fix this?
InputText.ts
export class InputTextComponent implements AfterViewInit, ControlValueAccessor {
#Input() disabled: boolean;
#Output() saveValue = new EventEmitter();
value: string;
onChange: () => void;
onTouched: () => void;
writeValue(value: any) {
this.value = value ? value : "";
}
registerOnChange(fn: any) {this.onChange = fn}
registerOnTouched(fn: any) {this.onTouched = fn}
setDisabledState(isDisabled) {this.disabled = isDisabled}
}
InputText.html
<input kendoTextBox />
Not sure this is what you are asking but in order to use formControlName inside a custom component here is what you do
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { InputTextComponent } from './input-text';
#NgModule({
declarations: [
AppComponent,
InputTextComponent
],
imports: [
FormsModule,
ReactiveFormsModule,
BrowserModule,
],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<form [formGroup]="details">
<input-text formControlName="name"></input-text>
<!-- This should show the name as you change it in your custom control -->
{{details.value | json}}
</form>
app.component.ts
import { Component } from '#angular/core';
import { FormGroup, FormControl } from '#angular/forms';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
public details: FormGroup;
constructor(
) {
this.details = new FormGroup({
name: new FormControl("name")
});
}
}
input-text.component.html
<input kendoTextBox [(ngModel)]="value" (ngModelChange)="onChange($event)" />
input-text.component.ts
import { Component, forwardRef } from "#angular/core";
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "#angular/forms";
#Component({
selector: "input-text",
templateUrl: "./input-text.html",
styleUrls: ["./input-text.scss"],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputTextComponent),
multi: true
}
]
})
export class InputTextComponent implements ControlValueAccessor {
public value: string;
propagateChange = (value: string) => {};
writeValue(obj: any): void {
this.value = obj;
}
registerOnTouched(fn: any): void {}
registerOnChange(fn) {
this.propagateChange = fn;
}
onChange(newValue){
this.propagateChange(newValue);
}
}
Related
I'm building a 'hello world' app using NGRX, but the state of my app keeps the initial value even when I'm triggering actions that should change it.
This is my app.module:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { StoreModule } from '#ngrx/store';
import { StoreDevtoolsModule } from '#ngrx/store-devtools';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { counterReducer } from './contador.reducer';
import { environment } from 'src/environments/environment';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
StoreModule.forRoot({ counter: counterReducer }),
StoreDevtoolsModule.instrument({
maxAge: 25,
logOnly: environment.production,
})
],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts:
import { Component, OnInit } from '#angular/core';
import { Store } from '#ngrx/store';
import { decrement, increment } from './contador/contador.actions';
interface AppState {
counter: number
}
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
public counter!: number;
constructor(private store: Store<AppState>) {
this.store.subscribe(state => {
console.log('state', state)
this.counter = state.counter;
})
}
ngOnInit() { }
inc() {
this.store.dispatch(increment())
}
dec() {
this.store.dispatch(decrement())
}
}
app.component.html:
<div class="container-fluid text-center">
<div class="row">
<div class="col pt-5">
<h1>Counter</h1>
<h2>{{counter}}</h2>
</div>
</div>
<button (click)="inc()" class="btn btn-primary pr-5">increment</button>
<button (click)="dec()" class="btn btn-primary pr-5">decrement</button>
</div>
counter.reducer.ts:
import { decrement, increment } from './contador/contador.actions';
import { Action, createReducer, on } from "#ngrx/store";
export const initialState = 20;
const _counterReducer = createReducer(initialState,
on(increment => initialState + 1),
on(decrement => initialState - 1)
)
export function counterReducer(initialState: number | undefined, actions: Action) {
return _counterReducer(initialState, actions)
}
contador.actions.ts
import { createAction } from "#ngrx/store"
export const increment = createAction('[counter] increment')
export const decrement = createAction('[counter] decrement')
The only thing I'm seeing is that in the reducer, the increment and decrement imports are not being used in the on() methods as they are unused imports.
I always get the initialValue = 0, no matter if I click the increment or decrement buttons.
The on cases in you reducer are not defined correctly.
The first argument is the action, second argument is a function which takes the existing state, then returns a modified version of it according to the specified action.
const _counterReducer = createReducer(initialState,
on(increment, state => state + 1),
on(decrement, state => state - 1)
);
I'm a beginner in Angular, and use BreadCrumb in my project. I have no problem with other pages, but when I want to show my child node details, I can only see the product id.
My project is here, and this is my code.
core.module.ts:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { NavBarComponent } from './nav-bar/nav-bar.component';
import { RouterModule } from '#angular/router';
import { TestErrorComponent } from './test-error/test-error.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { ServerErrorComponent } from './server-error/server-error.component';
import { ToastrModule } from 'ngx-toastr';
import { BreadcrumbModule } from 'xng-breadcrumb';
import { SectionHeaderComponent } from './section-header/section-header.component';
#NgModule({
declarations: [NavBarComponent, TestErrorComponent, NotFoundComponent, ServerErrorComponent, SectionHeaderComponent],
imports: [
CommonModule,
RouterModule,
BreadcrumbModule,
ToastrModule.forRoot({
positionClass: 'toast-bottom-right',
preventDuplicates: true
})
],
exports: [NavBarComponent, SectionHeaderComponent]
})
export class CoreModule { }
shop.routing.module.ts:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { Routes, RouterModule } from '#angular/router';
import { ShopComponent } from './shop.component';
import { ProductDetailsComponent } from './product-details/product-details.component';
const routes: Routes = [
{ path: '', component: ShopComponent },
{ path: ':id', component: ProductDetailsComponent, data: { breadCrumb: { alias: 'productDetails' } }}
];
#NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forChild(routes)
],
exports: [RouterModule]
})
export class ShopRoutingModule { }
product-details.component.ts:
import { Component, OnInit } from '#angular/core';
import { IProduct } from '../../shared/models/product';
import { ShopService } from '../shop.service';
import { ActivatedRoute } from '#angular/router';
import { BreadcrumbService } from 'xng-breadcrumb';
#Component({
selector: 'app-product-details',
templateUrl: './product-details.component.html',
styleUrls: ['./product-details.component.scss']
})
export class ProductDetailsComponent implements OnInit {
product: IProduct;
constructor(private shopService: ShopService, private activatedRoute: ActivatedRoute, private bcService: BreadcrumbService) { }
ngOnInit(): void {
this.loadProduct();
}
loadProduct() {
this.shopService.getProduct(+this.activatedRoute.snapshot.paramMap.get('id')).subscribe(product => {
this.product = product;
this.bcService.set('#productDetails', product.name);
}, error => {
console.log(error);
});
}
}
I gave my project link to check all of my code if you need it. Thanks for the help!
This happened when I debugged my project on chrome:
seems you have a typing error,
in shop-routing-module.ts it should be breadcrumbnot breadCrumb
data: { breadcrumb: { alias: 'productDetails' } },
I need to display all the names I have written in the table in the Angular field.
I have DB:
CREATE TABLE [dbo].[Sellers](
[Id] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[Login] [varchar](50) NOT NULL,
[Password] [varchar](50) NOT NULL,
[Name] [nchar](50) NOT NULL,
[Address] [nchar](50) NOT NULL,
[Email] [varchar](50) NOT NULL,
[RegistrationDate] [datetime] NOT NULL,
)
GO
I am requesting ASP web API to bring all the names from the table:
public class SellersController : ApiController
{
[HttpGet]
public async Task<IHttpActionResult> GetNames(string name)
{
using (var dataBaseContext = new DataBaseContext())
{
var query = from seller in dataBaseContext.Sellers
where
seller.Name == name
select seller;
return Ok(await query.ToListAsync());
}
}
}
I'll bring it to the angular. But it is not displayed and generally cries out the code:
import { Sellers } from './sellers.model';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class SellersService {
formData : Sellers;
constructor() { }
}
________________
<div class="p-3 px-md-4 mb-3 bg-white">
<input name="Sellers" #Sellers="ngModel"[(ngModel)] = "service.formData" class="form-control">
</div>
Nothing is displayed and the last line of the code issues an error
Can't bind to 'ngModel' since it isn't a known property of 'input'.Angular
UPD:
import { SellersService } from './shared/sellers.service';
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { HttpModule } from '#angular/http';
import { FormsModule } from '#angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TopRegionComponent } from './components/top-region/top-region.component';
import { LeftRegionComponent } from './components/left-region/left-region.component';
import { BottomRegionComponent } from './components/bottom-region/bottom-region.component';
import { CenterRegionComponent } from './components/center-region/center-region.component';
import { UserComponent } from './components/user/user.component';
const appRoutes: Routes = [
{path: '', component: AppComponent},
{path: 'user', component: UserComponent},
{path: 'left-region', component: LeftRegionComponent},
{path: 'top-region', component: TopRegionComponent},
{path: 'bottom-region', component: BottomRegionComponent},
{path: 'center-region', component: CenterRegionComponent},
]
#NgModule({
declarations: [
AppComponent,
TopRegionComponent,
LeftRegionComponent,
BottomRegionComponent,
CenterRegionComponent,
UserComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
RouterModule.forRoot(appRoutes),
HttpModule,
FormsModule
],
providers: [SellersService],
bootstrap: [AppComponent]
})
export class AppModule { }
UPD2:
import { SellersService } from './../../shared/sellers.service';
import { Component, OnInit } from '#angular/core';
import {Http} from '#angular/http';
import { FormsModule } from '#angular/forms';
#Component({
selector: 'left-region',
templateUrl: './left-region.component.html',
styleUrls: ['./left-region.component.css']
})
export class LeftRegionComponent implements OnInit {
constructor(private service : SellersService)
{
}
ngOnInit() {
}
}
I have given an example for your query kindly look into it.
import { Sellers } from './sellers.model';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class SellersService {
formData : Sellers;
seller : Sellers = new Sellers();
constructor() { }
}
HTML
<div class="p-3 px-md-4 mb-3 bg-white">
<input name="Sellers" #Sellers="ngModel" [(ngModel)]= "seller.Name" class="form-control">
</div>
The solution below was the first attempt as below.
Created app.module.ts and app.route.ts.
Created default for app.component.ts. The app.component router is working as expected so far for the first level routing.
Created a new module called Dashboard, with dashboard.module.ts and dashboard.routes.ts.
I imported the dashboard into the app.module.ts.
Created Sitebar,Header, and HeaderNav in the Dashboard.component.ts with child . But, no idea why the child navigation always shows in the first level router-outlet, instead of the child router-outlet.
Dashboard.component.ts code below.
<div class="wrapper">
<app-mydash-sidebar
[headerText]="'No Rush'"
[headerLink]="'http://www.bit-numbers.com'"
[headerLogoImg]="'/assets/img/angular2-logo-white.png'"
[backgroundColor]="'red'"
[backgroundImg]="'/assets/img/sidebar-5.jpg'"
[navItems]="navItems">
</app-mydash-sidebar>
<div class="main-panel">
<app-mydash-navbar [navItems]="navItems"></app-mydash-navbar>
<router-outlet ></router-outlet>
</div>
</div>
app.component.ts below.
<router-outlet></router-outlet>
Any idea?
app.routes.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { MembersComponent } from './members/members.component';
import { AuthGuard } from './auth.service';
import { SignupComponent } from './signup/signup.component';
import { EmailComponent } from './email/email.component';
import { HomeComponent } from './home/home.component';
import { BookingsComponent } from './bookings/bookings.component';
export const router: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'signup', component: SignupComponent },
{ path: 'login-email', component: EmailComponent },
{ path: 'members', component: MembersComponent, canActivate: [AuthGuard] },
{ path: '', component: LoginComponent},
{ path: 'bookings', component: BookingsComponent },
];
export const routes: ModuleWithProviders = RouterModule.forRoot(router);
mydash.routes.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AuthGuard } from '../auth.service';
import { MydashBookingsComponent } from '../mydash/mydash-bookings/mydash-bookings.component';
import { MydashChartComponent } from '../mydash/mydash-chart/mydash-chart.component';
import { MydashDashboardComponent } from '../mydash-dashboard/mydash-dashboard.component';
export const Dashboardrouter: Routes = [
{
path: 'dashboard',
children: [{
path: '',
pathMatch: 'full',
component: MydashDashboardComponent
},
{
path: 'mybookings',
component: MydashBookingsComponent
}]
}
];
export const DashboardRouting: ModuleWithProviders = RouterModule.forChild(Dashboardrouter);
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AngularFireModule } from 'angularfire2';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { EmailComponent } from './email/email.component';
import { SignupComponent } from './signup/signup.component';
import { MembersComponent } from './members/members.component';
import { AuthGuard } from './auth.service';
import { routes } from './app.routes';
import { IconsComponent } from './icons/icons.component';
import { NotificationsComponent } from './notifications/notifications.component';
import { UserComponent } from './user/user.component';
import { MydashModule } from './mydash/mydash.module';
import { HomeComponent } from './home/home.component';
import { BookingsComponent } from './bookings/bookings.component';
import {FirebaseServiceService} from './services/firebase-service.service';
// Must export the config
export const firebaseConfig = {
...
};
#NgModule({
declarations: [
AppComponent,
LoginComponent,
EmailComponent,
SignupComponent,
MembersComponent,
IconsComponent,
NotificationsComponent,
UserComponent,
HomeComponent,
BookingsComponent,
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
AngularFireModule.initializeApp(firebaseConfig),
MydashModule,
routes,
],
providers: [AuthGuard,FirebaseServiceService],
bootstrap: [AppComponent],
})
export class AppModule { }
mydash.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { MydashChartComponent } from './mydash-chart/mydash-chart.component';
import { MydashCheckboxComponent } from './mydash-checkbox/mydash-checkbox.component';
import { MydashCloseLayerComponent } from './mydash-close-layer/mydash-close-layer.component';
import { MydashFooterComponent } from './mydash-footer/mydash-footer.component';
import { MydashNavbarComponent } from './mydash-navbar/mydash-navbar.component';
import { MydashSidebarComponent } from './mydash-sidebar/mydash-sidebar.component';
import { MydashSidebarItemsComponent } from './mydash-sidebar-items/mydash-sidebar-items.component';
import { MydashTableComponent } from './mydash-table/mydash-table.component';
import { MydashTaskListComponent } from './mydash-task-list/mydash-task-list.component';
import { MydashUserProfileComponent } from './mydash-user-profile/mydash-user-profile.component';
import { MydashNavbarItemsComponent } from './mydash-navbar-items/mydash-navbar-items.component';
import { MydashBookingsComponent } from './mydash-bookings/mydash-bookings.component';
import { DashboardRouting} from './mydash.routes';
import { MydashDashboardComponent } from '../mydash-dashboard/mydash-dashboard.component';
export interface DropdownLink {
title: string;
routerLink?: string;
}
export enum NavItemType {
Sidebar = 1, // Only ever shown on sidebar
NavbarLeft = 2, // Left-aligned icon-only link on navbar in desktop mode, shown above sidebar items on collapsed sidebar in mobile mode
NavbarRight = 3 // Right-aligned link on navbar in desktop mode, shown above sidebar items on collapsed sidebar in mobile mode
}
export interface NavItem {
type: NavItemType;
title: string;
routerLink?: string;
iconClass?: string;
numNotifications?: number;
dropdownItems?: (DropdownLink | 'separator')[];
}
#NgModule({
imports: [
CommonModule,
DashboardRouting,
],
declarations: [
MydashChartComponent,
MydashCheckboxComponent,
MydashCloseLayerComponent,
MydashFooterComponent,
MydashNavbarComponent,
MydashSidebarComponent,
MydashSidebarItemsComponent,
MydashTableComponent,
MydashTaskListComponent,
MydashUserProfileComponent,
MydashNavbarItemsComponent,
MydashBookingsComponent,
MydashDashboardComponent],
// These components are to export to allow access from the Dashboard. Do it manually, not done by ng CLI.
exports: [
MydashSidebarComponent,
MydashNavbarComponent,
MydashFooterComponent,
MydashChartComponent,
MydashTaskListComponent,
MydashTableComponent,
MydashUserProfileComponent,
MydashCloseLayerComponent,
MydashBookingsComponent
],
providers:[]
})
export class MydashModule { }
I solved the issue. The problem was because the dashboard component was missing in the file name mydash.routes.ts. I assigned the appropriate component underneath the path: 'dashboard', before the Child routes. Now, it works like a champ. Cheers!
The Answer code below.
path: 'dashboard',
component: MydashDashboardComponent,
children: [{
I am fairly new to Angular2 and I am having issues adding Dragula to my application. When I run the application an error is thrown prior to loading the home page:
Exception: Call to Node module failed with error: Prerendering failed because of error: ReferenceError: document is not defined
The error message mentions Prerending which I suspect is in relation to the project using asp-prerender-module.
I've tried to follow official tutorials from Dragula and forum posts. Below are my app.module and component file snippets (... denotes summarised code):
app.module.ts
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { UniversalModule } from 'angular2-universal';
import { AppComponent } from './components/app/app.component'
...
import { SearchComponent } from './components/search/search.component';
import { BrowserModule } from '#angular/platform-browser';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { Injectable } from '#angular/core';
import { DragulaModule } from 'ng2-dragula';
#NgModule({
bootstrap: [ AppComponent ],
declarations: [
AppComponent,
...
SearchComponent
],
imports: [
UniversalModule,
BrowserModule,
FormsModule,
DragulaModule,
CommonModule,
RouterModule.forRoot([
{ path: '', redirectTo: 'home', pathMatch: 'full' },
...
{ path: 'search', component: SearchComponent },
{ path: '**', redirectTo: 'home' }
])
]
})
export class AppModule {
}
search.component.ts
import { Component } from '#angular/core';
import { Http } from '#angular/http';
import { SearchService } from '../../services/search.service';
import { DragulaService } from 'ng2-dragula';
#Component({
selector: 'search',
template: require('./search.component.html'),
providers: [SearchService, DragulaService]
})
I suspect I am missing an a step when including Dragula, but I cannot figure out where. I have included both dragula (^3.7.2) and ng2-dragula (^1.3.0) in my package.json file.
your DragulaService initialization is wrong!! check Dragula documentation link
search.component.ts
import { Component } from '#angular/core';
import { Http } from '#angular/http';
import { SearchService } from '../../services/search.service';
import { DragulaService } from 'ng2-dragula';
#Component({
selector: 'search',
template: require('./search.component.html'),
providers: [SearchService]
})
expoert searchcomponent{
constructor(private dragulaService: DragulaService) {
console.log('DragulaService created');
}
}
Now you can play with drag and drop
If you want more control over drag and drop you can add events and options to dragulaService.
constructor(private dragulaService: DragulaService) {
dragulaService.drag.subscribe((value) => {
console.log(`drag: ${value[0]}`);
this.onDrag(value.slice(1));
});
dragulaService.drop.subscribe((value) => {
console.log(`drop: ${value[0]}`);
this.onDrop(value.slice(1));
});
dragulaService.over.subscribe((value) => {
console.log(`over: ${value[0]}`);
this.onOver(value.slice(1));
});
dragulaService.out.subscribe((value) => {
console.log(`out: ${value[0]}`);
this.onOut(value.slice(1));
});
}
private onDrag(args) {
let [e, el] = args;
// do something
}
private onDrop(args) {
let [e, el] = args;
// do something
}
private onOver(args) {
let [e, el, container] = args;
// do something
}
private onOut(args) {
let [e, el, container] = args;
// do something
}