ZakiMohammed / ng-bootstrap-5-dropdown-app

Bootstrap 5 Dropdown Angular App
https://ng-bootstrap-5-dropdown-app.netlify.app/
5 stars 6 forks source link

Problem with data beeing fetched from HTTP Request #2

Closed Maid-Sabanovic closed 2 years ago

Maid-Sabanovic commented 2 years ago

In your ngOnInit you get the data from the app.service and use map() operator:

ngOnInit(): void {
        this.items = this.appService.getFoods().
            map(
                code => (
                    {
                        id: code.code,
                        name: code.code
                    } as Item
                )
            );
    }

You can use that because your data is a local array so it's easy. But I retrieve data from HTTP Get request. It then is saying that I can't remap those two additional parameters "id" and "name". I tried this:

ngOnInit(): void {
       this.subscription = this.contactSearchService.currentCodes.pipe(
        map(
            code => (
                {
                    id: code.code,
                    name: code.code
                }
            )
        )).subscribe(Response => {
            this.items = Response
        })
    }

I'm using an array that is of type ResponsibilityCode which is like this:

export interface ResponsibilityCode {
    timestamp: Byte[];
    code: string;
    description: string;
    cancelDeletion: boolean;
    gruppe: string;
}

Can you help me with that?

ZakiMohammed commented 2 years ago

Hey @Maid-Sabanovic, can you send me the error details so that I can help you to solve the issue, thanks.

Maid-Sabanovic commented 2 years ago

Hey @Maid-Sabanovic, can you send me the error details so that I can help you to solve the issue, thanks.

Of course, so the errors are: Property 'code' does not exist on type 'ResponsibilityCode[]'. Type '{ id: any; name: any; }' is missing the following properties from type 'Item[]': length, pop, push, concat, and 26 more.

I'm just trying your example but with the data being not locally available as array and calling

export class AppService {
    getFoods(): Food[] {
        return [
                       ....

Instead I have data coming from an endpoint and I'm retrieving that with http request. So could you help me change your example to use hhtp requests instead of local array?

Maid-Sabanovic commented 2 years ago

@ZakiMohammed I asked on stackoverflow and both of the answers provided worked to get all the items: (https://stackoverflow.com/questions/71113337/angular-12-how-to-return-an-http-get-request-array-of-objects-and-assign-to-othe)

The only problem now is that, when dropdown expanded I don't have any checkboxes: Unbenannt2

But when I create a local array like you did in your example just with different data, the checkboxes work again.

getFoods(): ResponsibilityCode[] {
    return [
        {
            timestamp: null,
            code: 'EINKAUF',
            description: 'EINKAUFDESC',
            cancelDeletion: false,
            gruppe: 'Arbeitskreis'
        },
        {
            timestamp: null,
            code: 'blabla',
            description: 'EINKAUFDESC',
            cancelDeletion: false,
            gruppe: 'Arbeitskreis'
        },
        {
            timestamp: null,
            code: 'iwas',
            description: 'EINKAUFDESC',
            cancelDeletion: false,
            gruppe: 'Arbeitskreis'
        },

    ];
ngOnInit(): void {
        this.items = this.contactSearchService.getFoods().map(code => ({
            id: code.code,
            name: code.code
        } as Item));
    }

Unbenannt

ZakiMohammed commented 2 years ago

Hey @Maid-Sabanovic,

I have added async implementation for calling external API and feeding the data to the items array. You can check the recent commit changes.

For an overview, I have done the following changes to the single and multi-select dropdown shared components:

_items: Item[] = [];

@Input('items')
set items(items: Item[]) {
    this._items = items;
    this._items.map(item => {
        item.uuid = item.uuid || v4();
        item.checked = item.checked || false;
        item.visible = item.visible || true;
    });
    this.filtered = [...this._items];

    if (!this.filtered.length) {
        this.all.visible = false;
    } else {
        this.all.visible = true;
    }
}

I have made the @Input items as setter to take the value of the updated items from parent control. Before it was added to ngOnInit, that's why it was not taking the updated values once obtained data from API.

And on individual component you can simply make an API call and update the items array as follows:

ngOnInit(): void {
    this.appService.getFoodsAsync().subscribe(response => {
      this.items = response;
    })
} 

Hope it helps :)

Maid-Sabanovic commented 2 years ago

Hey @ZakiMohammed Thank you so much for your help, it works perfectly! 😊 Many respect to you for setting up a multiselect dropdown without using jquery.js or popper.js, I find that really impressive 💯 🎉 I hope your project is getting more attention because it's really underrated. It's really good setup within a component, so if I want more dropdown in my html template I could just add more elements I think? That would be really convenient for me.

Also I would like to stay in contact with you. I sent you a follow request here on github. Would be nice to stay in contact 😊

Greetings from Germany! 👍

PS: With your next comment you can close this issue 😄

ZakiMohammed commented 2 years ago

Hey @Maid-Sabanovic,

Thanks, man, I am really glad that you appreciated it. 😄

And of course, we can definitely be in touch and lemme know if I can be of any help anytime (and vice-versa), that's how we roll in our programming journey.

Stay Safe ✌️