I am implementing the abstract factory and the getitems method works and returns 2 items I mocked, however I am not sure how to render these items in the react component
my code is below
AbstractFactory.tsx
import * as React from 'react';
import { IAbstractFactoryProps } from "./IAbstractFactoryProps";
import { IAbstractFactoryState } from "./IAbstractFactoryState";
import styles from './Abstractfactory.module.scss';
import { escape } from '@microsoft/sp-lodash-subset';
import DaoFactory from "./DaoFactory";
import ICustomerDao from "./ICustomerDao";
import DataSources from "./DatasourcesEnum";
export default class Abstractfactory extends React.Component<IAbstractFactoryProps, {}> {
private customerDao: ICustomerDao;
constructor(props: IAbstractFactoryProps, state: IAbstractFactoryState) {
super(props);
this.setInitialState();
this.setDaos(props.datasource);
this.state = {
items: this.customerDao.listCustomers(),
};
}
public render(): React.ReactElement<IAbstractFactoryProps> {
return (
<div className={ styles.abstractfactory }>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
{this.state.items}
</div>
</div>
</div>
</div>
)
}
public setInitialState(): void {
this.state = {
items: []
};
}
private setDaos(datasource: string): void {
const data: any = datasource === "Sharepoint" ? DataSources.SharepointList : DataSources.JsonData;
this.customerDao = DaoFactory.getDAOFactory(data).getCustomerDAO();
//Now, its transparent for us a UI developers what datasource was selected
//this.customerDao.
}
}
Customer.ts
class Customer{
public id: string;
public firstName: string;
public lastName: string;
}
export default Customer;
Datasourcesenum.ts
enum DataSources {
SharepointList = "SharepointList",
JsonData = "JsonData"
}
export default DataSources;
DaoFactory.ts
import ICustomerDAO from "./ICustomerDAO";
import DataSources from "./DatasourcesEnum";
abstract class DAOFactory {
public abstract getCustomerDAO(): ICustomerDAO;
public static getDAOFactory(whichFactory: DataSources): DAOFactory {
switch (whichFactory) {
case DataSources.SharepointList:
return new SharepointListDAOFactory();
case DataSources.JsonData:
return new JsonDAOFactory();
default :
return null;
}
}
}
export default DAOFactory;
import SharepointListDAOFactory from "./SharepointListDAOFactory";
import JsonDAOFactory from "./JsonDAOFactory";
JsonDaoFactory.ts
import DAOFactory from "./DaoFactory";
import JsonCustomerDAO from "./JsonCustomerDAO";
import ICustomerDao from "./ICustomerDao";
class JsonDAOFactory extends DAOFactory {
public getCustomerDAO(): ICustomerDao{
return new JsonCustomerDAO();
}
}
export default JsonDAOFactory;
SharepointListDaoFactory.ts
import DaoFactory from "./DaoFactory";
import ICustomerDao from "./ICustomerDao";
import SharepointCustomerDao from "./SharepointCustomerDAO";
class SharepointListDAOFactory extends DaoFactory {
public getCustomerDAO(): ICustomerDao{
return new SharepointCustomerDao();
}
}
export default SharepointListDAOFactory;
JsonCustomerDao.ts
import ICustomerDao from "./ICustomerDao";
import Customer from "./Customer";
class JsonCustomerDAO implements ICustomerDao{
public insertCustomer(): number {
// implementation to be done by reader
return 1;
}
public deleteCustomer(): boolean {
// implementation to be done by reader
return true;
}
public findCustomer(): Customer {
// implementation to be done by reader
return new Customer();
}
public updateCustomer(): boolean {
// implementation to be done by reader
return true;
}
public listCustomers(): Customer[] {
// implementation to be done by reader
let c1: Customer= new Customer();
let c2: Customer= new Customer();
c1.id="3";
c1.firstName="Andrew";
c1.lastName="Valencia";
c2.id="4";
c2.firstName="Charles";
c2.lastName="Smith";
let list: Array<Customer> = [c1, c2 ];
return list;
}
}
export default JsonCustomerDAO;
SharepointCustomerDao.ts
import ICustomerDao from "./ICustomerDao";
import Customer from "./Customer";
class SharepointCustomerDao implements ICustomerDao {
public insertCustomer(): number {
// implementation to be done by reader
return 1;
}
public deleteCustomer(): boolean {
// implementation to be done by reader
return true;
}
public findCustomer(): Customer {
// implementation to be done by reader
return new Customer();
}
public updateCustomer(): boolean {
// implementation to be done by reader
return true;
}
public listCustomers(): Customer[] {
// implementation to be done by reader
let c1: Customer = new Customer();
c1.id="1";
c1.firstName="Luis";
c1.lastName="Valencia";
let c2: Customer = new Customer();
c2.id="2";
c2.firstName="John";
c2.lastName="Smith";
let list: Array<Customer> = [c1, c2 ];
return list;
}
}
export default SharepointCustomerDao;
Icustomerdao
import Customer from "./Customer";
interface ICustomerDao {
insertCustomer(): number;
deleteCustomer(): boolean;
findCustomer(): Customer;
updateCustomer(): boolean;
listCustomers(): Customer[];
}
export default ICustomerDao;
.tsx
import * as React from 'react';
import { IAbstractfactoryProps } from "./IAbstractFactoryProps";
import { IAbstractFactoryState } from "./IAbstractFactoryState";
import styles from './Abstractfactory.module.scss';
import { escape } from '@microsoft/sp-lodash-subset';
import DaoFactory from "./DaoFactory";
import ICustomerDao from "./ICustomerDao";
import DataSources from "./DatasourcesEnum";
export default class Abstractfactory extends React.Component<IAbstractfactoryProps, {}> {
private customerDao: ICustomerDao;
constructor(props: IAbstractfactoryProps, state: IAbstractFactoryState) {
super(props);
this.setInitialState();
this.setDaos(props.datasource);
}
public render(): React.ReactElement<IAbstractfactoryProps> {
this.state = {
items: this.customerDao.listCustomers(),
};
return null;
}
public setInitialState(): void {
this.state = {
items: []
};
}
private setDaos(datasource: string): void {
const data: any = datasource === "Sharepoint" ? DataSources.SharepointList : DataSources.JsonData;
this.customerDao = DaoFactory.getDAOFactory(data).getCustomerDAO();
}
}
UPDATE 1
I changed the render method as below
public render(): React.ReactElement<IAbstractFactoryProps> {
return (
<div className={ styles.abstractfactory }>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
{this.state.items.map( i => (<div>i.id</div>)}
</div>
</div>
</div>
</div>
);
}
and I have these 2 issues
[23:11:06] Error - typescript - src/webparts/abstractfactory/components/Abstractfactory.tsx(34,63): error TS1005: ',' expected.
[23:11:06] Error - typescript - src/webparts/abstractfactory/components/Abstractfactory.tsx(34,30): error TS2339: Property 'items' does not exist on type 'Readonly<{}>'.
Fragments in React Now you can render multiple DOM nodes. In order to do this, wrap it inside a parent div which essentially makes it a single DOM node with multiple elements inside it. Fragments in React do not deviate much from their literal meaning.
Rendering Multiple Elements To render multiple JSX elements in React, you can loop through an array with the . map() method and return a single element.
We have to only return a single element from a React component because it's invalid syntax to return multiple values from a function.
** Update ** Okay, then lets leave the listCustomers method as is.
According to your code and the contents of the render method
items
equals to the customer array right?
if so then replace
{this.state.items}
with
{this.state.items.map( i => (<div>i.id</div>)}
for instance.
Sidenote: React re-renders components when their state changes. So whenever you make an update to your customerList, make sure to put it to the state of the component which is rendering them.
If you want to render multiple components with custom jsx you can create a function that takes the object and returns jsx like so:
const myCustomer =({id,name,phone}){
//Do stuff here
return(<div><span>{name}</span><span>{phone}</span></div>)
}
then you call it from your component in your render like so:
items.map((customer,i)=> <myCustomer key={i} {...customer}/>)
Note: if you need to keep state for each row you can use a React.Component instead of a function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With