0

Trying to move the getFiltersInfo function to a store but when i get back the data i got an empty array! I was told that i have to create a promise because of fetch takes time to be back! This is The Original Component where the function is

<script>
    import { onMount, onDestroy } from 'svelte';
    import * as api from '$lib/api';
    import { get as getStore } from 'svelte/store';
    import { session } from '$app/stores';
    import Filter from '../../../../../store/Filter';
    import FilData from '../../../../../store/FilData';
    import FiltersStore from '../../../../../store/Filters';
    import SingleFilter from '../../../../../store/SingleFilter';
    import ComboList from '$lib/components/Result/SearchResult/FilterComponent/ComboList/index.svelte';
    import CheckBoxList from '$lib/components/Result/SearchResult/FilterComponent/CheckBoxList/index.svelte';
    import RangeSelector from '$lib/components/Result/SearchResult/FilterComponent/RangeSelector/index.svelte';
    import { ShowFilter } from '../../../../../store/ShowFilter';
    import { ShowFilterContent } from '../../../../../store/ShowFilterContent';

    export let filterModelID;

    let { token } = getStore(session);
    let filters = [];

    // onMount(() => {
    //  getFilterModel();
    // });
    // let status;
    // FilData.subscribe((data) => {
    //  status = true;
    //  filters = data.filterData;
    // });
    $: getFilterModel();

    // FiltersStore.subscribe((data) => {
    //  filters = [...data];
    // });

    function getFilterModel() {
        let filterModel = $SingleFilter;
        getFiltersInfo(filterModel);
    }

    // function getFiltersInfo(Filters) {
    //  FiltersStore.getFiltersInfo(Filters, token);
    // }
     function getFiltersInfo(Filters) {
        let filters_ = Filters.filterModel.filters;
        filters_.forEach(async (filterId) => {
            const filter = await api.get(`filter/${filterId}`, token);
            Filter.getAttributeData(filter.filter.attribute, token);
            filters = [...filters, filter];
        });
     }
    $: console.log('filtersfiltersfiltersfiltersfiltersfiltersfiltersfilters', filters);
</script>

<div class="w-full  rounded-lg bg-white shadow-md p-2 mb-2">
    <div class=" flex items-center ">
        <img src="static/images/icons-png/filter-icon.png" alt="" />
        <span class="text-[16px] font-bold text-gray-600 ml-3">Filter:</span>
    </div>

    <div class="mt-5" />
    {#if filters}
        {#each filters as filterItem}
            {#if filterItem.filter.graphicalRepresentation?.fieldType == 'combo_box'}
                <div class="mt-2">
                    <ComboList
                        title={filterItem.filter.name}
                        attribute={filterItem.filter.attribute}
                        on:ComboListValue
                    />
                </div>
            {/if}

            {#if filterItem.filter.graphicalRepresentation?.fieldType == 'check_box'}
                <h2 class="text-[20px] font-light italic mt-3">{filterItem.filter.name}</h2>
                <hr />
                <div class="mt-2 p-2">
                    <CheckBoxList
                        attribute={filterItem.filter.attribute}
                        title={filterItem.filter.name}
                        on:checkboxValue
                    />
                </div>
            {/if}
            <!-- !TODO: Fix issue with the range_box  -->
            <!-- {#if filterItem.filter.graphicalRepresentation?.fieldType == 'range_box'}
                <hr class="w-[50%] left-[25%] relative" />
                <div class=" mb-[25px] px-2 pt-2">
                    <RangeSelector
                        title={filterItem.filter.name}
                        attribute={filterItem.filter.attribute}
                        on:RangeSelectorChange
                    />
                </div>
            {/if} -->
        {/each}
    {/if}
</div>

And this is store i want to move it to :

import { writable } from 'svelte/store';
import * as api from '$lib/api';
import Filter from './Filter';
import SingleFilter from './SingleFilter';

const Filters = writable([]);

const customFilters = {
    subscribe: Filters.subscribe,
    getFiltersInfo: (fils, token) => {
        let f = [];
        let filters_ = fils.filterModel.filters;
        filters_.forEach(async (filterId) => {
            const filter = await api.get(`filter/${filterId}`, token);
            Filter.getAttributeData(filter.filter.attribute, token);
            f = [...f, filter];
        });
        let promise = new Promise((resolve, reject) => {
            resolve([...f]);
        });
        promise.then((data) => (f = [...data])).catch((err) => console.log(err));
        console.log('fffffffffffffffffffffff', f);
        Filters.set(f);
    }
};

export default customFilters;
Abdel
  • 51
  • 4
  • If you need to wait for the forEach loop to complete to set the array result: https://advancedweb.hu/how-to-use-async-functions-with-array-foreach-in-javascript/ – voscausa May 10 '22 at 13:26
  • 1
    `'../../../../../store/Filter'` - I would recommend adding additional aliases like `$lib` and convert those paths to be relative to that, e.g. `$store`, then this becomes just `'$store/Filter'`. – H.B. May 10 '22 at 14:28
  • Please check https://stackoverflow.com/q/37576685/546730 - There are multiple issues with this code, though. The `promise` is completely useless, some of the array spreads are also not needed and this unnecessarily mixes `async`/`await` with callbacks (`then()`/`catch()`). – H.B. May 10 '22 at 14:58

0 Answers0