Expanding the HTTP Get URL with a click in Ionic 2 and Angular 2

I recently performed a search for my ionic app, which fetches data from an api using a http get method as shown below

static get parameters() {
    return [[Http]];
}

searchRecipes(id) {
    var url = 'http://api.yummly.com/v1/api/recipes?_app_id=/////&_app_key=//////&q=' + encodeURI(id);
    var response = this.http.get(url).map(res => res.json());
    return response;
}

Currently, I have the id that the user inputs. Now, I aim to include filters in my search like ingredients, cuisine, and allergies. This involves extending the url with specific calls such as &allowedAllergy[] and allowedDiet[].

I have already implemented a list of items where each has a predetermined value. Clicking on one item will append it to the url provided, similar to how it is done on

      <div class="diets">
        <ul>
          <li>Lacto vegetarian</li>
          <li>Ovo vegetarian</li>
          <li>PaleoPescetarian</li>
          <li>Vegan</li>
          <li>Vegetarian</li>
        </ul>
    </div>
    <div class="allergies">
      <ul>
        <li>Dairy-Free</li>
        <li>Egg-Free</li>
        <li>Gluten-Free</li>
        <li>Peanut-Free</li>
        <li>Seafood-Free</li>
        <li>Sesame-Free</li>
        <li>Soy-Free</li>
        <li>Sulfite-Free</li>
        <li>Tree Nut-Free</li>
        <li>Wheat-Free</li>
      </ul>
    </div>

Search Method

recipes: any;

searchRecipeDB(event, key) {
    if(event.target.value.length > 2) {
        this.apiAuthentication.searchRecipes(event.target.value).subscribe(
            data => {
                this.recipes = data.matches; 
                console.log(data);
            },
            err => {
                console.log(err);
            },
            () => console.log('Recipe Search Complete')
        );
    }
}

If you have any suggestions on how to go about implementing this, it would be greatly appreciated! Thanks in advance

Answer №1

Here is the component code snippet:

import {Component, OnInit} from "@angular/core"
import {Http} from "@angular/http"

@Component({
    selector: 'app-menu',
    templateUrl: './menu.component.html'
})
export class MenuComponent implements OnInit
{
    diets: Array<string> = ['Lacto vegetarian', 'Ovo vegetarian', 'PaleoPescetarian', 'Vegan', 'Vegetarian'];
    allergies: Array<string> = ['Dairy-Free',
                                'Egg-Free',
                                'Gluten-Free',
                                'Peanut-Free',
                                'Seafood-Free',
                                'Sesame-Free',
                                'Soy-Free',
                                'Sulfite-Free',
                                'Tree Nut-Free',
                                'Wheat-Free'];


    id: number = 1;
    selectedDiets: Array<boolean>;
    selectedAllergies: Array<boolean>;
    allowedAllergy: Array<string>;
    allowedCuisine: Array<string>;
    url: string;

    constructor(private http: Http)
    {
        this.selectedDiets = new Array(this.diets.length).fill(false);
        this.selectedAllergies = new Array(this.allergies.length).fill(false);
    }

    ngOnInit()
    {
    }

    submit()
    {
        this.processAllergy();
        this.processDiets();
        this.searchRecipes(this.id, this.allowedAllergy, this.allowedCuisine);
    }

    processAllergy()
    {

        this.allowedAllergy = this.selectedAllergies.reduce((selectedList: Array<string>, isSelected: boolean, index: number) =>
        {
            return isSelected ? [...selectedList, this.allergies[index]] : selectedList;
        }, [])

    }

    processDiets()
    {
        this.allowedCuisine = this.selectedDiets.reduce((selectedList: Array<string>, isSelected: boolean, index: number) =>
        {
            return isSelected ? [...selectedList, this.diets[index]] : selectedList;
        }, [])

    }

    searchRecipes(id: number,
                  allowedAllergy: Array<string>,
                  allowedCuisine: Array<string>)
    {


        this.url = 'http://api.yummly.com/v1/api/recipes?_app_id=/////&_app_key=//////&q=' + encodeURI(id.toString());


        if (allowedAllergy.length)
        {
            this.url = this.url + `&allowedAllergy=${encodeURI(allowedAllergy.toString())}`
        }
        if (allowedCuisine.length)
        {
            this.url = this.url + `&allowedCuisine=${encodeURI(allowedCuisine.toString())}`
        }


        console.log(this.url);
        //return this.http.get(url).map(res => res.json());
    }
}

And here is the corresponding view:

<pre>selectedDiets: {{selectedDiets | json}}</pre>
<pre>selectedAllergies: {{selectedAllergies | json}}</pre>
<pre>allowedAllergy: {{allowedAllergy | json}}</pre>
<pre>selectedAllergies: {{allowedCuisine | json}}</pre>
<div class="diets">
  <strong>Select diet regiments</strong>
  <ul>
    <li *ngFor="let diet of diets; let i = index">
      {{diet}}
      <input type="checkbox"
             [(ngModel)]="selectedDiets[i]">
    </li>
  </ul>
</div>

<div class="allergies">
  <strong>Select allergy requirements</strong>
  <ul>
    <li *ngFor="let allergy of allergies; let i = index">
      {{allergy}}
      <input type="checkbox"
             [(ngModel)]="selectedAllergies[i]">
    </li>
  </ul>
</div>
<pre>{{url}}</pre>
<button (click)="submit()">
  search
</button>

Answer №2

Here is a simple solution that should meet your needs:

searchRecipes(id: number,
              allowedAllergy: Array<string>,
              allowedCuisine: Array<string>)
{
    let url = 'http://api.deliciousmenu.com/v1/recipes?_app_id=/////&_app_key=//////&q=' + encodeURI(id.toString());

    if (allowedAllergy.length)
    {
        url = url + `&allowedAllergy=${allowedAllergy.toString()}`
    }
    if (allowedCuisine.length)
    {
        url = url + `&allowedCuisine=${allowedCuisine.toString()}`
    }

    return this.http.get(url).map(res => res.json());
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The correlation between a TypeScript class and an interface bearing an identical name

I have been struggling to find clear documentation or explanation for the unique relationship between a TypeScript class and an interface that share the same name. What is the significance of having an interface with the same name as a class? Why does a ...

The Express request parameter ID throws an error due to the index expression not being of type 'number', causing the element to implicitly have an 'any' type

Is there a way to assign a type to an ID request parameter? It appears that the types of Express treat request params as any. This is the code snippet where I am trying to access the ID from the request: const repository: Repository = { ...reposit ...

Tips for preserving the Context API state when navigating between pages in Next.js

Currently, I am working on a project that involves using nextJs and TypeScript. To manage global states within my application, I have implemented the context API. However, a recurring issue arises each time I navigate between pages - my state re-evaluates ...

What is the best way to execute a function on the output of *ngFor directive in Angular 2?

Imagine having a list of all the users within your system: allUsers = { a: {name:'Adam',email:'<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="39585d5854794d5c4a4d5a56175a56... f: {name:'fred' ...

The module named "mongoose" does not have any member called 'PaginateResult' exported

I'm facing an issue while trying to add the necessary types for "mongoose-paginate" in my Angular 4 project setup with "angular-cli". The problem arises when Webpack throws an error. import {PaginateResult} from "mongoose"; ... getAll(page: number) ...

Instructions on invoking a setter method in Angular

I am looking to implement a setter method to update my form. When should I invoke the setter method? Below is the code snippet from my component.ts: export class UpdateZoneComponent implements OnInit { profileForm: FormGroup products: any; h: number; c ...

Angular 2 feature that allows for a single list value to be toggled with the

Currently, my form is connected to a C# API that displays a list of entries. I am trying to implement a feature where two out of three fields can be edited for each line by clicking a button that toggles between Yes and No. When the button is clicked, it s ...

What is the best method for retrieving an item from localstorage?

Seeking advice on how to retrieve an item from local storage in next.js without causing a page rerender. Here is the code snippet I am currently using: import { ThemeProvider } from "@material-ui/core"; import { FC, useEffect, useState } from "react"; i ...

Encountering issue in Angular 14: Unable to assign type 'Date | undefined' to type 'string | number | Date' parameter

I have been working on an Angular 14 project where I am implementing a Search Filter Pipe. Below is the code snippet I am using: import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'transferFilter' }) export class Trans ...

What is the method for determining the width of a Mat-Table once it has been displayed?

When utilizing Angular Material Mat-Table in conjunction with Angular 8, I am passing the dataSource dynamically. The number of rows and columns varies each time. Is there a method to calculate the width of the table once it is rendered on the screen? &l ...

Incorporating fresh components and newly defined attributes in Angular

Is there a way for me to click on a new component button, specify a name, description, select type, and add attributes such as default value and type? I need all this information to be saved and for the new button to appear in the drag-and-drop section. ...

Toggle the visibility of a dropdown menu based on the checkbox being checked or unchecked

One challenge I am facing involves displaying and hiding DropDown/Select fields based on the state of a Checkbox. When the checkbox is checked, the Dropdown should be visible, and when unchecked, it should hide. Below is the code snippet for this component ...

Is it possible to utilize two ngForm elements within the same component in Angular 4?

Currently, I am in the process of creating a settings page that includes both profile update and password update forms. My goal is to have these two different forms within the same component. Is it feasible to integrate two form elements into one compone ...

There seems to be an issue with the Angular QuickStart project as it is not functioning properly, showing the error message "(

After following the instructions in this guide for setting up VS2015, I encountered issues when trying to run the "quick start" project or the "tour of heroes" tutorial on Google Chrome. The error message I received can be found here: Angular_QuickStart_Er ...

How do I retrieve and display all the locally stored variables in Angular 2/JavaScript and calculate the total number of keys present in the localStorage?

Currently, I'm developing a project in Angular2 that involves the storage of user-added items to a shopping cart. To accomplish this, I have opted to utilize local storage to temporarily save the items. Each category (such as shoes, clothes, etc.) is ...

Error: ionic serve is unable to locate the 'reflect-metadata' module

I am new to Ionic2 and following the steps: $ npm install -g ionic cordova $ ionic start cutePuppyPics --v2 $ cd cutePuppyPics $ ionic serve However, I encountered an error: "Cannot find module 'reflect-metadata' $ ionic info Cordova CLI: 6.5 ...

Organize Radio Selectors

My intention was to align the radio buttons as shown in the image below: https://i.stack.imgur.com/oPTjD.jpg However, the final result looked like this https://i.stack.imgur.com/Mixga.jpg Below is the code for your reference HTML <div class="form ...

Storing datepicker values in an Angular reactive form

Can anyone help me figure out how to effectively save the values of datepickers in a dynamic control? <tr *ngFor="let item of items"> <td style="padding-right: 20px">{{item.id}}</td> <td style="padding-right: 20px"> ...

Function generation using TypeScript

I'm in the process of creating a tool to automatically generate boilerplate code for me. The concept involves parsing all .json files within a folder called config, and then creating interfaces and auxiliary functions based on that data. Thanks to t ...

Enhance your Angular material datepicker with additional content such as a close button

I'm currently working on customizing my Angular Material datepicker by adding a button. The goal is to have this button placed in the top right corner and enable it to close the datepicker when clicked. In addition, I also want to include extra conte ...