1

I am getting the table column name as a status and I need to change the color of the buttons based on status value.

<ng-container matColumnDef="agentName">
    <th mat-header-cell *matHeaderCellDef>Agent Name</th>
    <td mat-cell *matCellDef="let element">{{element.agent_id.company_name}}</td>
</ng-container>

<ng-container matColumnDef="status">
    <th mat-header-cell *matHeaderCellDef>Status</th>
    <td mat-cell *matCellDef="let element"><span class="dot" [ngStyle]="{'background-color': getRowColor()}"></span></td>
</ng-container>

component.ts

// ...

export class Component {
    red = { 'background-color': 'red' }
    yellow = { 'background-color': '#DAA520' }
    green = { 'background-color': '#00FF00' }
    pageSizeOptions: number[];
    displayedColumns: string[] = ['title', 'agentName', 'status', 'star'];
    dat: any[] = [{
        id: 1,
        title: 'Test',
    }];
    state : any = [];
    getPos: any = [];

    dataSource: MatTableDataSource<{}>;
    @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;

    constructor(
        private store: Store<IAppState>,
        private userService: UserService,
        private poService: PoService,
        private propertiesService: PropertiesService,
        private _location: Location,
    ) {}

    ngOnInit() {
        this.getAllPO()
        this.pageSizeOptions = this.propertiesService.getPaginationSize()
    }

    edit(data) {
        this.poService.changeEditPurchaseOrder(data)
    }

    getAllPO() {
        const payload = {
            'company_id': this.userService.getUserdetails().CompanyUser.company_id.id,
        }

        this.showSpinner = true
        this.poSuccessSubscription.unsubscribe()
        this.poErrorSubscription.unsubscribe()
        this.store.dispatch(new GetAllPOs(payload))

        this.poSuccessSubscription = this.store
            .pipe(select(getAllPOsSuccess))
            .subscribe((result: any) => {
                if (!!result) {
                    this.getPos = result
                    this.state = this.getPos.find(element => {
                        return element.POMaterials.find(item =>{
                            return item.state
                        })
                    })
                    this.dataSource = new MatTableDataSource(result)
                    this.dataSource.paginator = this.paginator;
                    this.showSpinner = false
                } else {
                    this.dataSource = new MatTableDataSource([])
                    this.dataSource.paginator = this.paginator;
                    this.showSpinner = false
                }
            })

        this.poErrorSubscription = this.store
            .pipe(select(getAllPOsError))
            .subscribe((result: any) => {
                if (!!result) {
                    // alert(result.error)
                    this.showSpinner = false
                }
            })
    }

    getRowColor(state) {
        if (state === 'Not Received') {
            return 'red'
        } else if (state === 'Completed') {
            return '#00FF00'
        }
        else {
            return '#DAA520'
        }
    }

    applyFilter(filterValue: string) {
        this.dataSource.filter = filterValue.trim().toLowerCase();
        if (this.dataSource.paginator) {
            this.dataSource.paginator.firstPage();
        }
    }
}

My data looks like this. I need to get the value of state in each array and assign it to each row. Based on state value, I need to change the color of the buttons.

const result = [{
    Pomaterials: [{
        id: 1,
        state: 'not received'
    }],
    po_id: 1,
    mat_id: 3
}, {
    Pomaterials: [{
        id: 1,
        state: 'not received'
    }],
    po_id: 1,
    mat_id: 2
}];

4
  • I think you are looping through the result in your HTML. Can you please add that? Commented Jan 10, 2020 at 14:27
  • 2
    Reasoning about data structures when the lack of indentation makes it impossible to see it is quite hard. Start by doing the obvious: indent the code properly. Your IDE/editor can do that for you. Then please, clarify your question. Commented Jan 10, 2020 at 14:43
  • To add to the previous comment. Please share your entire component code(.ts and .html). There are a lot of missing pieces of functionality. I'm not able to connect any dots. Help us help you... Commented Jan 10, 2020 at 15:53
  • Now i edited my question.. you could check.. Commented Jan 10, 2020 at 16:06

2 Answers 2

1

Your HTML and your JSON result is confusing:

<td mat-cell *matCellDef="let element"> {{element.agent_id.company_name}} </td>

And

this.dataSource = new MatTableDataSource(result)

imply you should have an agent_id object, like:

const result = [
    {
      Pomaterials: [
        { 
         id:1,
         state:"not received"
        }
      ]
      po_id:1,
      mat_id:3,
      agent_id: {
          company_name: "Company"
      }
    },
    ...
]

Anyway, your getRowColor(state) function has a state param and you don't provide any from the HTML:

<td mat-cell *matCellDef="let element"><span class="dot" [ngStyle]="{'background-color': getRowColor()}"></span> </td>

As element is a row of your JSON result, you may try:

<td mat-cell *matCellDef="let element"><span class="dot" [ngStyle]="{'background-color': getRowColor(element.Pomaterials[0].state)}"></span> </td>

Only if your Pomaterials is always built like the JSON result you provide us.

If you need to loop over Pomaterials array for setting the state you can do something like:

this.poSuccessSubscription = this.store
    .pipe(select(getAllPOsSuccess))
    .subscribe((result: any) => {
      if (!!result) {
        ...
        this.getPos.forEach(element => {
          element.finalState = evalFinalStateElement(element.Pomaterials);
        });
        ...
      }
      ...
});

evalFinalStateElement(Pomaterials: Array<any>) {
  let finalState;
  Pomaterials.forEach(Po => {
    if(!finalState) {
      finalState = Po.state;
    }
    else if(finalState === 'XXX' && Po.state === 'YYY') {
      finalState = Po.state
    }
    // ...
  });
  return finalState;
}

And then use the defined element.finalState variable inside your HTML:

<td mat-cell *matCellDef="let element"><span class="dot" [ngStyle]="{'background-color': getRowColor(element.finalState)}"></span> </td>

with the getRowColor(state) function you posted.

Sign up to request clarification or add additional context in comments.

3 Comments

You should post as a code snippet. I'm not sure if this is actually any better than what OP posted :(
thank you so much... its working fine when i approach through html..
But if i have more than 1 POmaterials in an array.. then how can we approach??
0

You can send the whole POmaterials array as param of the getRowColor function and iter on elements for finding your value. Can you tell us what you want to do with your array?

9 Comments

Hi Pierre-Henri. You can answer to comments in the comment section (click the "add a comment" link underneath the comment). No need to make a separate answer for that.
i need to filter the value based on state in each array..before doing this i need to get together value of state in each array.. For example case1: pomaterials[0].state = "Not received" , pomaterials[1].state ="Completed" then final state should be not received.. First thing i need to get final state to loopover the array then based on those state i need to do filter opertion.. could you please help me out??
Hi TT, sorry for the bad posting, I am new on stackoverflow and just understand that using the website from my smartphone is not as good using my computer. I'd like to fix it but I think it is too late now.
Rekha, I updated my answer, not 100% sure it is what you need, let me now.
I got an error in ForEach of undefined in evalFinalstatevalue(element.Pomaterials)..
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.