JSON value into FormlyFirldConfig of Formly Form - angular-formly

I am trying to add a json file formatted to fit the formlyconfig file but unable to do so
Here is my HTML
<div class="row">
<div class="col-md-4 mb-4">
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<formly-form [form]="form"
[model]="model"
[fields]="fields">
</formly-form>
</form>
</div>
</div>
Here is my TS file
import { Component, OnInit } from '#angular/core';
import { FormGroup } from '#angular/forms';
import { ActivatedRoute, Router } from '#angular/router';
import { FormlyFieldConfig } from '#ngx-formly/core';
import { CheckListClient, CheckListDTO } from '../../web-api-client';
#Component({
selector: 'app-service-form-formly',
templateUrl: './service-form-formly.component.html',
styleUrls: ['./service-form-formly.component.css']
})
export class ServiceFormFormlyComponent implements OnInit {
checklistDtos: CheckListDTO[];
isEditable: boolean = true;
constructor(private clientChecklist: CheckListClient, private router: Router, private route: ActivatedRoute) { }
ngOnInit(): void {
this.filterChecklist();
}
filterChecklist() {
this.clientChecklist.getAllCheckList().subscribe(result => {
this.checklistDtos = result;
});
}
form = new FormGroup({});
model = {};
fields: FormlyFieldConfig[] = [
];
onSubmit() {
if (this.form.valid) {
alert(JSON.stringify(this.model, null, 2));
}
}
}
the JSON value is inside this.checklistDtos = result;
Please help me out with this

You have to put the result in fields, like
this.fields = result or
this.fields = this.checklistDtos

Related

I have been having issues in implementing a filter of item categories in an ecommerce being built using NodeJs and Angular

In the following
code snippets you the filter functions doesn't work.
Component HTML:
<div class="products-page">
<div class="grid">
<div class="col-3">
<h4>Categories</h4>
<div class="p-field-checkbox" *ngFor="let category of categories">
<label for="{{category.id}}">{{category.name}}</label>
<p-checkbox
[(ngModel)]="category.checked"
binary="true"
[inputId]="category.id"
(onChange)="categoryFilter()"
></p-checkbox>
<label for="{{ category.id }}">{{ category.name }}</label>
</div>
</div>
<div class="col-9">
<div class="grid" *ngIf="products">
<div class="col-4" *ngFor="let product of products">
<eshop-frontend-product-item [product] ="product"></eshop-frontend-product-item>
</div>
</div>
</div>
</div>
Component TS:
import { Component, OnInit } from '#angular/core';
import { ProductsService } from '../../services/products.service';
import { Product } from '../../models/product';
import { CategoriesService } from '../../services/categories.service';
import { Category } from '../../models/category';
#Component({
selector: 'eshop-frontend-products-list',
templateUrl: './products-list.component.html',
styles: [
]
})
export class ProductsListComponent implements OnInit {
isChecked = false
products: Product[] = [];
categories: Category[] = [];
constructor(private prodService: ProductsService, private catService: CategoriesService) { }
ngOnInit(): void {
this._getProducts();
this._getCategories();
}
private _getProducts(categoriesFilter?: string[]) {
this.prodService.getProducts(categoriesFilter).subscribe((resProducts) => {
this.products = resProducts;
});
}
private _getCategories(){
this.catService.getCategories().subscribe(resCats =>{
this.categories = resCats;
})
}
categoryFilter() {
const selectedCategories: string | any = this.categories
.filter((category) => category.checked)
.map((category) => category.id);
this._getProducts(selectedCategories);
}
}
Products Service:
import { Injectable } from '#angular/core';
import { HttpClient, HttpParams } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from '#env/environment';
import { Product } from '../models/product';
#Injectable({
providedIn: 'root',
})
export class ProductsService {
apiUrlProducts = environment.apiURL + 'products';
constructor(private http: HttpClient) {}
getProducts(categoriesFilter?: string[]): Observable<Product[]> {
let params = new HttpParams();
if (categoriesFilter) {
params = params.append('categories', categoriesFilter.join(','));
}
return this.http.get<Product[]>(this.apiUrlProducts, { params: params });
}
createProduct(productData: FormData): Observable<Product> {
return this.http.post<Product>(this.apiUrlProducts, productData);
}
getProduct(productId: string): Observable<Product> {
return this.http.get<Product>(`${this.apiUrlProducts}/${productId}`);
}
updateProduct(productData: FormData, productid: string): Observable<Product> {
return this.http.put<Product>(`${this.apiUrlProducts}/${productid}`, productData);
}
deleteProduct(productId: string): Observable<any> {
return this.http.delete<any>(`${this.apiUrlProducts}/${productId}`);
}
getProductsCount(): Observable<number> {
return this.http
.get<number>(`${this.apiUrlProducts}/get/count`)
.pipe(map((objectValue: any) => objectValue.productCount));
}
getFeaturedProducts(): Observable<Product[]>{
return this.http.get<Product[]>(`${this.apiUrlProducts}/get/featured/`);
}
}
Errors:
[(ngModel)]="category.checked"
Property 'checked' does not exist on type 'Category';
[inputId]="category.id"
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'
In the backend i do not have the checked field, I was under the impression that it was not necessary to add it, I have also witnessed several example where this is not implemented and still works fine. I have been stuk for a long time and there seems to be nothing useful out there, can you please advise?
[(ngModel)]="category.checked" Property 'checked' does not exist on type 'Category';
You can check in your interface in import { Category } from '../../models/category'; if there a property called checked. Otherwise, add the "checked" property to the category interface.
[inputId]="category.id" Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.
Again check your Category interface, maybe the property "id" has a type like that string | undefined. Remove the "| undefined" and it sould work.
models/category.ts:
export class Category {
id?: string;
name?: string;
icon?: string;
color?: string;
checked?: boolean;
}

Angular get blog by id not displaying anything on browser

I'm building a blog application based on MEAN stack, using Angular in front-end, node in back-end and mongoDB for server. When I'm trying to access a particular blog by it's blogId, the browser is not showing anything. Although I'm getting the right data fetched from backend with a 304 status and the right blogId is also passing by the route. The console is also logging the right object. Below is my blog-view.component.ts file
import { ActivatedRoute, Router } from '#angular/router';
import { ToastrManager } from 'ng6-toastr-notifications';
import { BlogService } from '../blog.service';
import { BlogHttpService } from '../blog-http.service';
import { Location } from '#angular/common';
#Component({
selector: 'app-blog-view',
templateUrl: './blog-view.component.html',
styleUrls: ['./blog-view.component.css'],
providers: [Location]
})
export class BlogViewComponent implements OnInit, OnDestroy {
public currentBlog;
constructor(private _route: ActivatedRoute, private router: Router, public blogHttpService:BlogHttpService, public toastr: ToastrManager, private location: Location) {
console.log("view-blog constructor called")
}
ngOnInit() {
console.log("view-blog ngOnInIt called");
let myBlogId = this._route.snapshot.paramMap.get('blogId');
console.log(myBlogId);
this.currentBlog = this.blogHttpService.getSingleBlogInformation(myBlogId).subscribe(
data =>{
console.log(data);
this.currentBlog = data["data"];
},
error =>{
console.log("some error occured");
console.log(error.errorMessage);
})
}
public deleteThisBlog(): any {
this.blogHttpService.deleteBlog(this.currentBlog.blogId).subscribe(
data =>{
console.log(data);
this.toastr.successToastr('This blog is successfully deleted.', 'Success!');
setTimeout(() =>{
this.router.navigate(['/home']);
}, 1000)
},
error =>{
console.log(error);
console.log(error.errorMessage);
this.toastr.errorToastr('Some Error Occured.', 'Oops!');
}
)
}
public goBackToPreviousPage(): any {
this.location.back();
}
ngOnDestroy(){
console.log("view-blog component destroyed");
}
}
blog-view.component.html
<div class="row" *ngIf="currentBlog" style="text-align: center;">
<div class="col-md-12">
<h2>{{currentBlog.title}}</h2>
<p>posted by {{currentBlog.author}} on {{currentBlog.created | date:'medium'}}</p>
<p *ngIf="currentBlog.tags!=undefined && currentBlog.tags.length>0">tags : <span *ngFor="let tag of currentBlog.tags;let first=first;let last=last">{{tag}}{{last ? '' : ', '}}</span></p>
<hr>
<div [innerHtml]="currentBlog.bodyHtml"></div>
<hr>
<h5>category - {{currentBlog.category}}</h5>
</div>
<hr>
<div class="row" *ngIf="currentBlog">
<div class="col-md-4">
<a class="btn btn-primary" [routerLink]="['/edit',currentBlog.blogId]">Edit</a>
</div>
<div class="col-md-4">
<a class="btn btn-danger" (click)="deleteThisBlog()">Delete</a>
</div>
<div class="col-md-4">
<a class="btn btn-warning" (click)="goBackToPreviousPage()">Go Back</a>
</div>
</div>
</div>
</div>
blog-http.service.ts
import { HttpClient, HttpErrorResponse } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
#Injectable()
export class BlogHttpService {
public allBlogs;
public currentBlog;
public baseUrl = 'http://localhost:3000/api/v1/blogs';
constructor(private _http:HttpClient) {
console.log('blog http service constructor called');
}
private handleError(err:HttpErrorResponse){
console.log("handle error http calls");
console.log(err.message);
return Observable.throw(err.message)
}
public getAllBlogs(): any {
let myResponse = this._http.get(this.baseUrl + '/all');
console.log(myResponse);
return myResponse;
}
public getSingleBlogInformation(currentBlogId): any {
let myResponse = this._http.get(this.baseUrl + '/view/' + currentBlogId);
return myResponse;
}
public createBlog(blogData): any {
let myResponse = this._http.post(this.baseUrl + '/create', blogData);
return myResponse;
}
public deleteBlog(blogId): any {
let data = {}
let myResponse = this._http.post(this.baseUrl + '/' + blogId + '/delete', blogId);
return myResponse;
}
public editBlog(blogId, blogData): any {
let myResponse = this._http.put(this.baseUrl + '/' + blogId + '/edit' , blogData);
return myResponse;
}
}
my nodejs routes with controller for blog-view
app.get(baseUrl+'/view/:blogId', (req, res) => {
BlogModel.findOne({ 'blogId': req.params.blogId }, (err, result) => {
if (err) {
console.log(err)
res.send(err)
} else if (result == undefined || result == null || result == '') {
console.log('No Blog Found')
res.send("No Blog Found")
} else {
res.send(result)
}
})
});
Below is a sample document object from which the frontend should render
{
"_id": "5e0e8ac6dcfc4e2008390cdf",
"blogId": "XAY2Qlhb",
"__v": 0,
"lastModified": "2020-01-03T00:28:54.638Z",
"created": "2020-01-03T00:28:54.638Z",
"tags": [
"english movies, action movies"
],
"author": "Decardo",
"category": "Hollywood custom",
"isPublished": true,
"views": 8,
"bodyHtml": "<h1>Heading of the body</h1>\n<p>This is the first blog data getting uploaded n blog project</p>",
"description": "long description>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",
"title": "Blog Title 1 custom"
}
This line of code will first store a Subscription in this.currentBlog:
this.currentBlog = this.blogHttpService.getSingleBlogInformation(myBlogId).subscribe(...)
Then the subscription will be overwritten by this.currentBlog = data["data"];
this.currentBlog = is actually not needed there.
Not sure if that is the problem. At least it is not proper :)

this.data.getUsers(...).subscribe is not a function

fetching details from API and trying to list the same getting error while printing the list of users was able print with same code.
following is my home.component.ts
constructor(private formBuilder: FormBuilder, private data: DataService) { }
ngOnInit() {
this.data.getUsers().subscribe(data => {
this.users = data
console.log(this.users);
}
);
}
following is my data services code
getUsers() {
return this.http.get('https://reqres.in/api/users');
}
following is the html loop I am trying
<ul *ngIf="users">
<li *ngFor="let user of users.data">
<img [src]="user.avatar">
<p>{{ user.first_name }} {{ user.last_name }}</p>
</li>
</ul>
Re-Check this from your code Working Stackblitz
component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from './data.service';
#Component({
selector: 'my-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
users;
constructor(private data: DataService){}
ngOnInit() {
this.data.getUsers().subscribe(data => {
this.users = data ;
})
}
}
service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable()
export class DataService {
constructor(private http: HttpClient) { }
getUsers() {
return this.http.get('https://reqres.in/api/users');
}
}
component.html
<ul *ngIf="users">
<li *ngFor="let user of users.data">
<img [src]="user.avatar">
<p>{{ user.first_name }} {{ user.last_name }}</p>
</li>
</ul>
Worked... I cleared cache of npm and it worked ..

Displaying images on angular app from node server

I have a nodejs app running on localhost:3000, I uploaded images using multer, so they are in ./uploads/ folder.
In the Angular app running on locahost:4200 I want to retrieve those images.
in my for loop: ( projectImages is the array of images for every Project Object)
<div *ngFor="let i of project.projectImages">
<img [src]=i.path alt="" >
</div>
the problem is that the path is being displayed as : localhost:4200/uploads/image.png instead of localhost:3000/uploads/image.png
UPDATE:
With that fixed by adding a variable to the component, I'm now getting :
WARNING: sanitizing unsafe URL value
any help would be appreciated!
UPDATE2:
this is my component:
import { Component, OnInit } from '#angular/core';
import { ProjectService } from '../services/project.service';
import { Router, ActivatedRoute } from '#angular/router';
import {Location} from '#angular/common';
import { DomSanitizer } from '#angular/platform-browser';
#Component({
selector: 'app-project-details',
templateUrl: './project-details.component.html',
styleUrls: ['./project-details.component.css']
})
export class ProjectDetailsComponent implements OnInit {
project:any;
apiUrl :string = "localhost:3000";
project_id:string;
constructor(
private router:Router,
private activatedRoute: ActivatedRoute,
private projectService:ProjectService,
private _location: Location,
private sanitization: DomSanitizer
) {
this.activatedRoute.params
.subscribe( params => {
console.log(params.project_id)
this.project_id = params.project_id;
this.getProjectByID(params.project_id);
})
}
ngOnInit() {
}
getProjectByID(project_id:string){
this.projectService.getProjectById(project_id).subscribe((data:any) => {
this.project = data.project;
this.project.projectImages.map(image => {
image.path = this.sanitization.bypassSecurityTrustUrl(`${this.apiUrl}/${image.path}`.replace(/\\/g,"/"));
console.log(image);
return image;
});
console.log(this.project.projectImages);
} , err => {
console.log(err);
});
}
}
NOTE: project.projectImages is an array containing the images, this is what it looks like: https://ibb.co/jEgszo
use full path and sanitize the url before use
import { DomSanitizer } from '#angular/platform-browser';
import { environment } from '../../../../environments/environment';
export class YourClass{
project;
apiUrl;
constructor(private sanitization: DomSanitizer) {
this.apiUrl = environment.apiUrl;
project.projectImages.map(image => {
image.path = this.sanitization.bypassSecurityTrustUrl(`${this.apiUrl}/${image.path}`);
return image;
});
}
}
then in your html you can do this
<div *ngFor="let i of project.projectImages">
<img [src]=i.path alt="" >
</div>
your complete code will look something like this
import { Component, OnInit } from '#angular/core';
import { ProjectService } from '../services/project.service';
import { Router, ActivatedRoute } from '#angular/router';
import { Location } from '#angular/common';
import { DomSanitizer } from '#angular/platform-browser';
import { environment } from '../../../../environments/environment';
#Component({
selector: 'app-project-details',
templateUrl: './project-details.component.html',
styleUrls: ['./project-details.component.css']
})
export class ProjectDetailsComponent implements OnInit {
project: any;
apiUrl: string;
project_id: string;
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
private projectService: ProjectService,
private _location: Location,
private sanitization: DomSanitizer
) {
this.apiUrl = environment.apiUrl;
this.activatedRoute.params
.subscribe(params => {
console.log(params.project_id)
this.project_id = params.project_id;
this.getProjectByID(params.project_id);
})
}
ngOnInit() {
}
getProjectByID(project_id: string) {
this.projectService.getProjectById(project_id).subscribe((data: any) => {
data.project.projectImages.map(image => {
image.path = this.sanitization.bypassSecurityTrustUrl(`${this.apiUrl}/${image.path}`);
return image;
});
this.project = data.project;
}, err => {
console.log(err);
});
}
}
check out the docs here
I guess you are using express in your node app, you need to include a static route to the resources/uploads directory (express static routes) like the following:
app.use(express.static('resources/uploads'))

*ngFor not working (angular 4)

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());
}
}

Resources