I'm using Angular 10 and the JW Angular Pagination module works fine if I import it into app.module.ts and then use it in a view that uses the app.component.ts component. However, when I try to import it into a custom feature module and use a component that imports the feature module, the pagination element does not display in the view template. It seems that Angular cannot see the pagination module.
App.module.ts
import { NgModule, Component, OnInit } from '#angular/core';
import { CoreModule } from "./core/core.module"
import { MessageModule } from "./messages/message.module";
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import * as $ from 'jquery';
import { BrowserModule } from '#angular/platform-browser';
import { AuthService } from "./model/auth.service"
import { JwPaginationModule } from 'jw-angular-pagination';
#NgModule({
imports: [AppRoutingModule, MessageModule, CoreModule, BrowserModule, JwPaginationModule],
declarations: [AppComponent,],
providers: [AuthService],
bootstrap: [AppComponent]
})
export class AppModule {
}
Core.module.ts
import { NgModule } from "#angular/core";
import { ModelModule } from "../model/model.module";
import { FormsFeatureModule } from "../view/forms.module";
import { ViewFeatureModule } from "../view/view.module";
import { routing } from "../app.routing";
import { MessageModule } from "../messages/message.module";
import { MessageService } from "../messages/message.service";
import { Message } from "../messages/message.model";
import { AuthService } from "../model/auth.service";
import { EncrDecrService } from '../utils/EncrDecr.service';
import { CommonModule } from '#angular/common';
//import { NotFoundComponent } from "./notFound.component";
//import { UnsavedGuard } from './unsaved.guard';
#NgModule({
imports: [ModelModule, MessageModule, routing, FormsFeatureModule, ViewFeatureModule, CommonModule],
declarations: [],
exports: [ModelModule, FormsFeatureModule, ViewFeatureModule, MessageModule ],
providers: [AuthService, EncrDecrService],
})
export class CoreModule {
}
Forms.module.ts
import { NgModule } from "#angular/core";
import { FormsModule, Validators, FormGroup, FormBuilder, NgForm } from '#angular/forms';
import { ReactiveFormsModule } from '#angular/forms';
import { BrowserModule } from '#angular/platform-browser';
import { RouterModule } from '#angular/router';
//import { NotFoundComponent } from "./notFound.component";
//import { UnsavedGuard } from './unsaved.guard';
import { ActivatedRoute, Router } from "#angular/router";
import { AuthService } from "../model/auth.service";
import { JwPaginationModule } from 'jw-angular-pagination';
#NgModule({
imports: [FormsModule, ReactiveFormsModule, BrowserModule, RouterModule, JwPaginationModule],
declarations: [],
exports: [FormsModule, ReactiveFormsModule, RouterModule, JwPaginationModule],
providers: [AuthService],
})
export class FormsFeatureModule {
constructor(private router: Router) { }
View.module.ts
import { RecipeViewComponent } from "../view/recipeView.component";
import { NgModule } from "#angular/core";
import { FormsModule } from '#angular/forms';
import { ReactiveFormsModule } from '#angular/forms';
import { BrowserModule } from '#angular/platform-browser';
import { RouterModule } from '#angular/router';
import { HomePageComponent } from "./homePage.component";
import { AdminComponent } from "../admin/admin.component";
import { AuthService } from "../model/auth.service";
//import { NotFoundComponent } from "./notFound.component";
//import { UnsavedGuard } from './unsaved.guard';
#NgModule({
imports: [FormsModule, ReactiveFormsModule, BrowserModule, RouterModule],
declarations: [RecipeViewComponent, HomePageComponent, AdminComponent],
exports: [RecipeViewComponent, HomePageComponent,AdminComponent, RouterModule],
providers: [AuthService],
})
export class ViewFeatureModule { }
admin.component.ts
import { Component, Inject, DoCheck, ChangeDetectorRef, OnInit } from "#angular/core";
import { ActivatedRoute, Router } from "#angular/router";
import { ModelRepo } from "../model/repository.model";
import { Category } from "../model/category.model";
import { Ingredient } from "../model/ingredient.model";
import { RecipeBook } from "../model/recipeBook.model";
import { User } from "../model/user.model";
import { FormsFeatureModule } from "../view/forms.module"
import { ViewChild, ElementRef } from '#angular/core';
import { EncrDecrService } from '../utils/EncrDecr.service';
import { AppComponent } from '../app.component'
import { Observable, throwError } from "rxjs";
//import { MODES, SharedState, SHARED_STATE } from "./sharedState.model";
//import { Observer} from "rxjs"
#Component(
{
selector: "admin",
templateUrl: "admin.component.html"
}
)
export class AdminComponent implements OnInit {
ModNewCategory = new Category(0,"");
ModNewIngredient = new Ingredient(0,"");
ModNewRecipeBook = new RecipeBook();
selectedConfig = "categories"; //initilze for first page load
selectedCategoryOperation = "addCategory"; //initilze for first page load
selectedIngredientOperation = "addIngredient"; //initilze for first page load
selectedUserOperation = "addUser"; //initilze for first page load
userRoles = new Array<string>("visitor", "member", "administrator");
searchRole = "";
id;
mode;
operation;
defaultObject = new Object();
public pageOfItems: Array<any>;
public items = [];
constructor(public dataRepo: ModelRepo, private EncrDecr: EncrDecrService, private appComponent:AppComponent, activeRoute: ActivatedRoute, public router: Router, public fieldValidator: FormsFeatureModule) {
activeRoute.params.subscribe(params => {
this.id = params["id"];
this.mode = params["mode"];
this.operation = params["operation"]
if (this.operation != null && this.mode != null) {
this.modifyItem(this.id, this.operation);
}
}
)
}
ngOnInit() {
// an example array of 150 items to be paged
// this.items = this.dataRepo.users;
this.items = Array(150).fill(0).map((x, i) => ({ id: (i + 1), name: `Item ${i + 1}` }));
}
onChangePage(pageOfItems: Array<any>) {
// update current page of items
alert('onChangePage got called');
this.pageOfItems = pageOfItems;
}
admin.component.html
<div class="card text-center m-3">
<h3 class="card-header">Angular Pagination Example</h3>
<div class="card-body">
<div *ngFor="let item of pageOfItems">{{item.name}}</div>
</div>
<div class="card-footer pb-0 pt-3">
<jw-pagination [items]="items" (changePage)="onChangePage($event)"></jw-pagination>
</div>
</div>
The Problem
You are using Angular10...
Have a look at the below statement Ivy is not complaining about unknown element inside ng-template
#36171
This is due to an architectural change in Ivy. In the previous compiler (ViewEngine), the check for unknown elements would occur during parsing of the template. In Ivy, templates are parsed independently from the corresponding NgModule, so information on components/directives in scope is not available.
Instead, checking of elements is pushed into the template type checking phase and it's currently affected by the type checker's configuration. With fullTemplateTypeCheck set to true however, it should descend into templates to check them (when it's false, it won't for backwards compatibility reasons). This conflicts however with your statement here:
The issue can only be found in runtime (no component being rendered) or with fullTemplateTypeCheck: true.
Consider the imports array in the module you are declaring AdminComponent
imports: [FormsModule, ReactiveFormsModule, BrowserModule, RouterModule],
This module does not have any idea about a JwPaginationModule
Solution
The simplest solution is to simply add JwPaginationModule to this array
imports: [FormsModule, ReactiveFormsModule, BrowserModule, RouterModule, JwPaginationModule],
Now the module will know about this component and render correctly.
Related
Trying to inject my own GoogleService to use it in Facility schema's pre-save hook. But as soon as i add imports: [GoogleModule], pre-save hook is not invoked without any errors. Same type of injection works with default ConfigModule fine.
google.module.ts:
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { GoogleService } from './google.service';
#Module({
imports: [ConfigModule],
providers: [GoogleService],
exports: [GoogleService]
})
export class GoogleModule { }
facilities.module.ts:
import { MongooseModule } from '#nestjs/mongoose';
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import * as zip2tz from 'zipcode-to-timezone';
import { FacilitiesService } from './facilities.service';
import { UsersModule } from '../users/users.module';
import { ShiftTemplatesModule } from '../shift-templates/shift-templates.module';
import { FacilitiesController } from './facilities.controller';
import { Facility, FacilitySchema, FacilityDocument } from './schemas/facility.schema';
import { MailerModule } from '../thirdparty/mailer/mailer.module';
import { ServicedStatesModule } from './../serviced-states/serviced-states.module';
import { GoogleModule } from '../thirdparty/google/google.module';
import { GoogleService } from '../thirdparty/google/google.service';
#Module({
imports: [
ShiftTemplatesModule,
MongooseModule.forFeatureAsync([{
imports: [GoogleModule],
inject: [GoogleService],
name: Facility.name,
useFactory: async (googleService: GoogleService) => {
const schema = FacilitySchema;
schema.pre<FacilityDocument>('save', async function (next) {
console.log('****************************8') //this isn't invoked, however it is with no imports
console.log('PRESAVE')
if (!this.timezone || this.isModified('address')) {
this.timezone = zip2tz.lookup(this.address.zip) || 'America/New_York';
}
if (!this.address.lat || !this.address.long || this.isModified('address')) {
this.address = await googleService.attachCoordinatesToAddress(this.address);
}
next();
});
return schema;
}
}]),
UsersModule,
MailerModule,
ConfigModule,
ServicedStatesModule,
GoogleModule
],
controllers: [FacilitiesController],
providers: [FacilitiesService],
exports: [FacilitiesService]
})
export class FacilitiesModule { }
I'm trying to connect an Angular Project with a NodeJs API, the issue is that the request doesn't work on Angular side, tho it works well in console and browser.
I tried it in console like:
curl http://127.0.0.1:3333/table
And I got back the response:
[{"userid":2,"roleid":2,"username":"partner2","fullname":"His Full Name","psw":"gmail#gail.com","email":"password","balance":0}]%
I assume there are some issues on Angular side.
Would you have any idea how to fix it?
// app.modules.ts
import { BrowserAnimationsModule } from '#angular/platform-browser/animations'; // this is needed!
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { RouterModule } from '#angular/router';
import { AppRoutingModule } from './app.routing';
import { ComponentsModule } from './components/components.module';
import { ExamplesModule } from './examples/examples.module';
import { AppComponent } from './app.component';
import { NavbarComponent } from './shared/navbar/navbar.component';
import {HTTP_INTERCEPTORS, HttpClientModule} from '#angular/common/http';
import {AuthInterceptor} from './auth.interceptor';
import {BrowserModule} from '#angular/platform-browser';
#NgModule({
declarations: [
AppComponent,
NavbarComponent
],
imports: [
BrowserModule,
HttpClientModule,
BrowserAnimationsModule,
NgbModule,
FormsModule,
RouterModule,
AppRoutingModule,
ComponentsModule,
ExamplesModule
],
providers: [
/*{
provide : HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi : true,
},*/
],
bootstrap: [AppComponent]
})
export class AppModule { }
// services.services.ts
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http';
import {Observable} from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class ServiceService {
constructor(private httpClient: HttpClient) {
}
public createNewUser(bodyParams: any): Observable<any> {
return this.httpClient.post('carriers/new-carrier', bodyParams);
}
public getTableX(): Observable<any> {
return this.httpClient.get('http://localhost:3003/api/table');
}
public getTableZ(): Observable<any> {
return this.httpClient.get('http://localhost:3003/table');
}
public getTable(): Observable<any> {
return this.httpClient.get('http://127.0.0.1:3333/table');
}
}
You should fix that issue at your packend side, browser need responses with allowed cors Cross-Origin please check https://expressjs.com/en/resources/middleware/cors.html when you are using Espress Node js.
This issue has been fixed through adding below line to my proxy
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
https://medium.com/#dtkatz/3-ways-to-fix-the-cors-error-and-how-access-control-allow-origin-works-d97d55946d9
I've imported the required modules also checked for errors but nothing helps.
I am new to angular and still learning.
Here's is my app.module.ts file
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { CommonModule } from "#angular/common";
import { AppComponent } from './app.component';
import { ContactsComponent } from './contacts/contacts.component';
#NgModule({
declarations: [
AppComponent,
ContactsComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
CommonModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
And here's the part of the code which is not working, but not working throwing any error either.
<div class="container">
<div *ngFor = "let contact of contacts" >
<div class = "col-md-3">
{{contact.first_name}}
</div>
<div class = "col-md-3">
{{contact.last_name}}
</div>
<div class = "col-md-3">
{{contact.phone}}
</div>
<div class = "col-md-3">
<input type="button" (click)="deleteContact(contact._id)" value ="Delete" class="btn btn-danger" />
</div>
</div>
</div>
Update: I've included my contact.srevice.ts file.
import { Injectable } from '#angular/core';
import {Http, Headers} from '#angular/http';
import {Contact} from './contact';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class ContactService {
constructor(private http: Http) { }
//retrieving contact_service
getContacts() :Observable<any[]>
{
return this.http.get('http://localhost:3000/api/contacts')
.map(res => res.json());
}
//add contact method
addContact(newContact){
var headers = new Headers();
headers.append('Content-Type','application/json');
return this.http.post('http://localhost:3000/api/contact', newContact, {headers:headers})
.map(res=>res.json());
}
//delete Contact Method
deleteContact(id){
return this.http.delete('http://localhost:3000/api/contact/'+id)
.map(res=>res.json());
}
}
Network Activity
As per your .ts code you need to bind some data with your object named as contacts like this to get it work
contacts = [
{first_name: "Pardeep", last_name: "Jain", phone: '90'},
{first_name: "Pardeep", last_name: "Jain", phone: '90'},
{first_name: "Pardeep", last_name: "Jain", phone: '90'}
]
Working Example
Update
You need to bind data whatever you get from this service like this -
ngOnInit() {
this.service.getContacts()
.subscribe(data=> this.contacts = data)
}
you need to do like this
import { Component } from '#angular/core';
import {Contact} from './contact';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'] })
export class AppComponent implements OnInit
{
title = 'New App';
contacts: Contact[];
ngOnInit() {
this.service.getContacts()
.subscribe(data=> this.contacts = data)
}
}
contact.service.ts file
//make use of newer api of http
import { HttpClient, HttpHeaders } from '#angular/common/http';
export class ContactService {
constructor(private http: HttpClient) { }
getContacts() :Observable<Contact[]>
{
return
this.http.get<Contact[]>('http://localhost:3000/api/contacts');
}
addContact(newContact) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
};
return this.http.post('http://localhost:3000/api/contact', newContact, httpOptions)
.map(res=>res.json());
}
}
Situation:
I'm using Angular CLI. And I'm trying to receive data from the server side (node.js, express). I created new component card-object. I copied this code from the example on this page: https://angular.io/guide/http
app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { HttpClientModule } from '#angular/common/http';
import { MatGridListModule, MatCardModule } from '#angular/material';
import { AppComponent } from './app.component';
import { CardObjectComponent } from './card-object/card-object.component';
#NgModule({
declarations: [
AppComponent,
CardObjectComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
MatGridListModule,
MatCardModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html:
<app-card-object></app-card-object>
card-object.component.ts:
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-card-object',
templateUrl: './card-object.component.html',
styleUrls: ['./card-object.component.css'],
encapsulation: ViewEncapsulation.None
})
export class CardObjectComponent implements OnInit {
results: string[];
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.http.get('http://localhost:3000/?cll=bjc').subscribe(data => {
this.results = data['results'];
});
}
}
card-object.component.html:
<p>{{results[0]}}</p>
<p>some text</p>
node.js:
app.get('/', (req, res) => {
var reqCard = {
results: ['text 1', 'text 2']
};
res.json(reqCard);
});
Problem:
I see that json data I receive successfully (I can see them in google DevTool => Network => XHR). But everything that I see in my angular app is 'some text'. And I see ERROR TypeError: Cannot read property '0' of undefined in my DevTool console.
Question:
Where is a mistake? What have I missed?
Initialize your array so that it has a value before the async call completes:
ngOnInit(): void {
this.results = []
this.http.get('http://localhost:3000/?cll=bjc').subscribe(data => {
this.results = data['results'];
});
}
Bind if results has data:
<p>{{results.length > 0 ? results[0]: ''}}</p>
<p>some text</p>
I don't know but, Some weird thing happening up, I referred the default code provided on "Angular.io" to perform angular service calls, but some how ngOninit method is not getting called.
I have also implemented component from OnInit. and added #Injectable to user.services.ts. But still don't know where I am getting wrong.
Below is the code for the reference.
app.component.ts
//app.components.ts
import { Component } from '#angular/core';
import {User} from './user';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Society CRM';
}
user.ts
export class User
{
_id : string;
name: string;
email: string;
username: string;
password: string;
phone: string;
address: string;
role: string;
created_date: string;
}
user-list.component.ts
import {Component,OnInit} from '#angular/core';
import {User} from './user';
import {UserService} from './user.service';
import { Headers, RequestOptions } from '#angular/http';
#Component({
selector:'user-list',
templateUrl:'./user-list.html',
providers: [ UserService ]
})
export class UserListComponent implements OnInit{
errorMessage: string;
users: User[];
mode = 'Observable';
constructor (private userService: UserService) {};
ngOnInit() {
this.getUsersList();
alert('here');
}
getUsersList() {
return this.userService.getUsersList()
.subscribe(
users => this.users = users,
error => this.errorMessage = <any>error);
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import { UserListComponent } from './user-list.component';
import { UserService } from './user.service';
import { FormsModule } from '#angular/forms'; // <-- NgModel lives here
#NgModule({
declarations: [
AppComponent,
UserListComponent
],
imports: [
BrowserModule,
HttpModule,
FormsModule
],
providers: [UserService],
bootstrap: [AppComponent]
})
export class AppModule { }
user.service.ts
import {Injectable} from '#angular/core';
import {Http, Response} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import {User} from './user';
import { Headers, RequestOptions } from '#angular/http';
#Injectable()
export class UserService
{
constructor (private http:Http){}
private api_url = "http://localhost:3000/api/";
getUsersList() : Observable<User[]>
{
let headers = new Headers();
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('Access-Control-Allow-Methods', 'GET');
headers.append('Access-Control-Allow-Headers', 'Content-Type');
let options = new RequestOptions({headers: headers});
return this.http.get(this.api_url+'getUsersList',options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.data || {};
}
private handleError(error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
I don't know what exactly is happening with the above code, no error being shown on firebug console or browser console. Any help would be thankful
Change your app.component.html code by adding this:
<user-list></user-list>
OnInit isn't called because you don't use user-list.component.
Check that you indeed use the component...
For example is the tag <user-list></user-list> defined somewhere in your html?