-3

I am trying to recreate the search functionality of outlook. My entire data set is contained in the following interfaces:

export interface Folder{
    id: string | null;
    name: string;
    folders: Folder[] | null;
    emails: Email[]
}

export interface Email {
    id : string;
    conversation_id: string;
    from: Contact;
    to: Contact[];
    cc: Contact[];
    bcc: Contact[];
    subject: string;
    body: string;
    body_preview: string;
    has_attachments: boolean;
    file_attachments: FileAttachment[];
    received_date: Date
}

export interface Contact
{
    email_address : number;
    name : string | null;
}

export interface FileAttachment
{
    id: string;
    file_name: string;
    content_type: string;
    content_bytes: string;
}

As you can see it is a complex object with multiple layers and unknown depth as the folders can contain more folders and more emails. I have the following v-text-field which I will be using to search for strings in my nested object:

            <v-text-field
        v-model="search"
        append-inner-icon="mdi-magnify"
        label="Dynamic Search"
        density="compact"
        variant="outlined"
        clearable
        rounded
        hide-details
        single-line
        flat
        color="primaryDarken4"/> 

I am looking to see an answer which shows how to maintain this structure of the objects but filters down the emails to those containing atleast 1 matching string in one of its properties.

8
  • This question is similar to: How can I access and process nested objects, arrays, or JSON?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem.
    – jabaa
    Commented Jul 3 at 21:05
  • I missed this. Let me look it over.
    – Qiuzman
    Commented Jul 3 at 21:08
  • My question is much different. Mine is specifically about looping through the nested object dynamically/recursively and returnining back only the email components if the nested email object has a match at one of its properties.
    – Qiuzman
    Commented Jul 3 at 21:15
  • The section "What if the property names are dynamic and I don't know them beforehand?" describes dynamic access. The section "What if the "depth" of the data structure is unknown to me?" describes recursive access. Returning only email components can be achieved with a simple map. That's also described in the other question.
    – jabaa
    Commented Jul 3 at 21:16
  • This questions : stackoverflow.com/questions/8085004/… is the closest I have found to what I need but still doesnt describe to to return the object still in its shape but only filtered on the email objects in my case.
    – Qiuzman
    Commented Jul 3 at 21:17

1 Answer 1

2

This functions will help

 function filterEmails(emailData: Email, searchTerm: string): boolean {
    const searchTermLwCase = searchTerm.toLowerCase();
    return (
        emailData.subject.toLowerCase().includes(searchTermLwCase) ||
        emailData.body.toLowerCase().includes(searchTermLwCase) ||
        emailData.body_preview.toLowerCase().includes(searchTermLwCase) ||
        emailData.from.name?.toLowerCase().includes(searchTermLwCase) ||
        emailData.to.some(contact => contact.name?.toLowerCase().includes(searchTermLwCase)) ||
        emailData.cc.some(contact => contact.name?.toLowerCase().includes(searchTermLwCase)) ||
        emailData.bcc.some(contact => contact.name?.toLowerCase().includes(searchTermLwCase))
    );
}

function searchForEmails(folder: Folder, searchTerm: string): Folder {
    // emails filtered from current folder
    const filteredEmails = folder.emails.filter(email => filterEmails(email, searchTerm));

    // subfolder filter recursively
    const filteredFolders = folder.folders ? folder.folders.map(subfolder => searchFolders(subfolder, searchTerm)).filter(subfolder => subfolder.emails.length > 0 || (subfolder.folders && subfolder.folders.length > 0)) : [];

   
    return {
        ...folder,
        emails: filteredEmails,
        folders: filteredFolders
    };
}
1
  • Could you provide an alternative answer in this using the approach showing the function returning the folder object with the the emails limited to the filtered ones as you have done? Your answer is working beautifully but if I did decide to show folders eventually I would need to maintain the object structure but the emails filtered.
    – Qiuzman
    Commented Jul 3 at 21:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.