Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I resolve the issue of being unable to utilize the codegen auto-generated AppSync API code in my Amplify Angular application? #368

Open
saidberk27 opened this issue Aug 14, 2024 Discussed in #367 · 0 comments

Comments

@saidberk27
Copy link

Discussed in #367

Originally posted by saidberk27 August 14, 2024
I am relatively new to AWS and Angular development. I am currently working on a project where AWS IoT sends data to a specific topic, which triggers a Lambda function. This Lambda function then stores the data in DynamoDB, and my AppSync API reads from this DynamoDB table.

Objective:
My goal is to create a real-time IoT web application. Specifically, I want to frequently check DynamoDB for any updates, as I expect changes to occur approximately six times per minute due to the IoT device's activity.

Current Progress:
I have tested my AppSync API, and it successfully reacts to new data published to the IoT channel. I can see the newly added item's partition key (though not the full data), indicating that the API is responsive to IoT events.

Issue:
I am encountering difficulties when attempting to integrate this API with my Angular 18 application, which is built using AWS Amplify.

I have followed the documentation to configure my application, as shown below:

// app.config.ts

Amplify.configure(outputs); // For auth and data
Amplify.configure({
  API: {
    GraphQL: {
      endpoint: 'https://xxx.appsync-api.xx-xx-2.amazonaws.com/graphql',
      region: 'xx-xx-2',
      defaultAuthMode: 'apiKey',
      apiKey: 'da2-xxx'
    }
  }
});

Subsequently, I used the codegen feature to generate a service file for my API.

/* tslint:disable */
/* eslint-disable */
//  This file was automatically generated and should not be edited.
import { Injectable } from "@angular/core";
import { Client, generateClient, GraphQLResult } from "aws-amplify/api";
import { Observable } from "rxjs";

export type __SubscriptionContainer = {
  onCreateIotTest: OnCreateIotTestSubscription;
  onUpdateIotTest: OnUpdateIotTestSubscription;
  onDeleteIotTest: OnDeleteIotTestSubscription;
};

export type CreateIotTestInput = {
  iot_test: string;
};

export type IotTest = {
  __typename: "IotTest";
  iot_test: string;
};

export type UpdateIotTestInput = {
  iot_test: string;
};

export type DeleteIotTestInput = {
  iot_test: string;
};

export type TableIotTestFilterInput = {
  iot_test?: TableStringFilterInput | null;
};

export type TableStringFilterInput = {
  ne?: string | null;
  eq?: string | null;
  le?: string | null;
  lt?: string | null;
  ge?: string | null;
  gt?: string | null;
  contains?: string | null;
  notContains?: string | null;
  between?: Array<string | null> | null;
  beginsWith?: string | null;
  attributeExists?: boolean | null;
  size?: ModelSizeInput | null;
};

export type ModelSizeInput = {
  ne?: number | null;
  eq?: number | null;
  le?: number | null;
  lt?: number | null;
  ge?: number | null;
  gt?: number | null;
  between?: Array<number | null> | null;
};

export type IotTestConnection = {
  __typename: "IotTestConnection";
  items?: Array<IotTest | null> | null;
  nextToken?: string | null;
};

export type CreateIotTestMutation = {
  __typename: "IotTest";
  iot_test: string;
};

export type UpdateIotTestMutation = {
  __typename: "IotTest";
  iot_test: string;
};

export type DeleteIotTestMutation = {
  __typename: "IotTest";
  iot_test: string;
};

export type GetIotTestQuery = {
  __typename: "IotTest";
  iot_test: string;
};

export type ListIotTestsQuery = {
  __typename: "IotTestConnection";
  items?: Array<{
    __typename: "IotTest";
    iot_test: string;
  } | null> | null;
  nextToken?: string | null;
};

export type OnCreateIotTestSubscription = {
  __typename: "IotTest";
  iot_test: string;
};

export type OnUpdateIotTestSubscription = {
  __typename: "IotTest";
  iot_test: string;
};

export type OnDeleteIotTestSubscription = {
  __typename: "IotTest";
  iot_test: string;
};

@Injectable({
  providedIn: "root"
})
export class APIService {
  public client: Client;
  constructor() {
    this.client = generateClient();
  }
  async CreateIotTest(
    input: CreateIotTestInput
  ): Promise<CreateIotTestMutation> {
    const statement = `mutation CreateIotTest($input: CreateIotTestInput!) {
        createIotTest(input: $input) {
          __typename
          iot_test
        }
      }`;
    const gqlAPIServiceArguments: any = {
      input
    };
    const response = (await this.client.graphql({
      query: statement,
      variables: gqlAPIServiceArguments
    })) as any;
    return <CreateIotTestMutation>response.data.createIotTest;
  }
  async UpdateIotTest(
    input: UpdateIotTestInput
  ): Promise<UpdateIotTestMutation> {
    const statement = `mutation UpdateIotTest($input: UpdateIotTestInput!) {
        updateIotTest(input: $input) {
          __typename
          iot_test
        }
      }`;
    const gqlAPIServiceArguments: any = {
      input
    };
    const response = (await this.client.graphql({
      query: statement,
      variables: gqlAPIServiceArguments
    })) as any;
    return <UpdateIotTestMutation>response.data.updateIotTest;
  }
  async DeleteIotTest(
    input: DeleteIotTestInput
  ): Promise<DeleteIotTestMutation> {
    const statement = `mutation DeleteIotTest($input: DeleteIotTestInput!) {
        deleteIotTest(input: $input) {
          __typename
          iot_test
        }
      }`;
    const gqlAPIServiceArguments: any = {
      input
    };
    const response = (await this.client.graphql({
      query: statement,
      variables: gqlAPIServiceArguments
    })) as any;
    return <DeleteIotTestMutation>response.data.deleteIotTest;
  }
  async GetIotTest(iot_test: string): Promise<GetIotTestQuery> {
    const statement = `query GetIotTest($iot_test: String!) {
        getIotTest(iot_test: $iot_test) {
          __typename
          iot_test
        }
      }`;
    const gqlAPIServiceArguments: any = {
      iot_test
    };
    const response = (await this.client.graphql({
      query: statement,
      variables: gqlAPIServiceArguments
    })) as any;
    return <GetIotTestQuery>response.data.getIotTest;
  }
  async ListIotTests(
    filter?: TableIotTestFilterInput,
    limit?: number,
    nextToken?: string
  ): Promise<ListIotTestsQuery> {
    const statement = `query ListIotTests($filter: TableIotTestFilterInput, $limit: Int, $nextToken: String) {
        listIotTests(filter: $filter, limit: $limit, nextToken: $nextToken) {
          __typename
          items {
            __typename
            iot_test
          }
          nextToken
        }
      }`;
    const gqlAPIServiceArguments: any = {};
    if (filter) {
      gqlAPIServiceArguments.filter = filter;
    }
    if (limit) {
      gqlAPIServiceArguments.limit = limit;
    }
    if (nextToken) {
      gqlAPIServiceArguments.nextToken = nextToken;
    }
    const response = (await this.client.graphql({
      query: statement,
      variables: gqlAPIServiceArguments
    })) as any;
    return <ListIotTestsQuery>response.data.listIotTests;
  }
  OnCreateIotTestListener(
    iot_test?: string
  ): Observable<
    GraphQLResult<Pick<__SubscriptionContainer, "onCreateIotTest">>
  > {
    const statement = `subscription OnCreateIotTest($iot_test: String) {
        onCreateIotTest(iot_test: $iot_test) {
          __typename
          iot_test
        }
      }`;
    const gqlAPIServiceArguments: any = {};
    if (iot_test) {
      gqlAPIServiceArguments.iot_test = iot_test;
    }
    return this.client.graphql({
      query: statement,
      variables: gqlAPIServiceArguments
    }) as any;
  }

  OnUpdateIotTestListener(
    iot_test?: string
  ): Observable<
    GraphQLResult<Pick<__SubscriptionContainer, "onUpdateIotTest">>
  > {
    const statement = `subscription OnUpdateIotTest($iot_test: String) {
        onUpdateIotTest(iot_test: $iot_test) {
          __typename
          iot_test
        }
      }`;
    const gqlAPIServiceArguments: any = {};
    if (iot_test) {
      gqlAPIServiceArguments.iot_test = iot_test;
    }
    return this.client.graphql({
      query: statement,
      variables: gqlAPIServiceArguments
    }) as any;
  }

  OnDeleteIotTestListener(
    iot_test?: string
  ): Observable<
    GraphQLResult<Pick<__SubscriptionContainer, "onDeleteIotTest">>
  > {
    const statement = `subscription OnDeleteIotTest($iot_test: String) {
        onDeleteIotTest(iot_test: $iot_test) {
          __typename
          iot_test
        }
      }`;
    const gqlAPIServiceArguments: any = {};
    if (iot_test) {
      gqlAPIServiceArguments.iot_test = iot_test;
    }
    return this.client.graphql({
      query: statement,
      variables: gqlAPIServiceArguments
    }) as any;
  }
}

I then created a basic Angular component to interact with this API:

import { Component, OnInit } from '@angular/core';
import { APIService, CreateIotTestInput, DeleteIotTestInput, UpdateIotTestInput } from '../API.service';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-iot-test',
  template: `
    <div>
      <h1>Iot Test Component</h1>
      <button (click)="createIotTest()">Create Iot Test</button>
      <button (click)="updateIotTest()">Update Iot Test</button>
      <button (click)="deleteIotTest()">Delete Iot Test</button>
      <button (click)="getIotTest()">Get Iot Test</button>
      <button (click)="listIotTests()">List Iot Tests</button>
    </div>
  `,
  standalone: true,
  imports: [CommonModule],
  providers: [APIService]
})
export class IotTestComponent implements OnInit {
  constructor(private apiService: APIService) { }

  ngOnInit(): void {
  }

  createIotTest(): void {
    const input: CreateIotTestInput = {
      iot_test: 'New Iot Test'
    };
    this.apiService.CreateIotTest(input).then((response) => {
      console.log(response);
    });
  }

  updateIotTest(): void {
    const input: UpdateIotTestInput = {
      iot_test: 'Updated Iot Test'
    };
    this.apiService.UpdateIotTest(input).then((response) => {
      console.log(response);
    });
  }

  deleteIotTest(): void {
    const input: DeleteIotTestInput = {
      iot_test: 'Iot Test to delete'
    };
    this.apiService.DeleteIotTest(input).then((response) => {
      console.log(response);
    });
  }

  getIotTest(): void {
    const iot_test = 'Iot Test to get';
    this.apiService.GetIotTest(iot_test).then((response) => {
      console.log(response);
    });
  }

  listIotTests(): void {
    this.apiService.ListIotTests().then((response) => {
      console.log(response);
    });
  }
}

When I try to interact somehow with API service functions, I get validation errors. for example when I click List IoT Tests button I get two errors.

"Validation error of type UnknownType: Unknown type TableIotTestFilterInput"

and

"Validation error of type FieldUndefined: Field 'listIotTests' in type 'Query' is undefined @ 'listIotTests'"

FYI: I am running on localhost currently

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant