Skip to content

Commit 3ff3f21

Browse files
Angular-data-snippets (#8166)
* remove reference of renameModelFields * add code examples for angular * add angular specific code examples * add angular and vue examples * update vue example * add angular example for polly * add angular example for bedrock * add angular example for rekognition * remove complete example from angular and vue pages
1 parent e8599e5 commit 3ff3f21

File tree

7 files changed

+436
-16
lines changed

7 files changed

+436
-16
lines changed

src/pages/[platform]/build-a-backend/data/connect-to-existing-data-sources/connect-postgres-mysql-database/index.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ When deploying your app to production, you need to [add the database connection
208208

209209
## Rename generated models and fields
210210

211-
To improve the ergonomics of your API, you might want to rename the generate fields or types to better accommodate your use case. Use the `renameModels()` and `renameModelFields()` modifiers to rename the auto-inferred data models and their fields.
211+
To improve the ergonomics of your API, you might want to rename the generate fields or types to better accommodate your use case. Use the `renameModels()` modifier to rename the auto-inferred data models.
212212

213213
```ts
214214
// Rename models or fields to be more idiomatic for frontend code

src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-amazon-polly/index.mdx

+50
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ Amplify.configure(outputs);
218218

219219
Example frontend code to create an audio buffer for playback using a text input.
220220

221+
<InlineFilter filters={["react", "javascript", "nextjs", "react-native"]}>
221222
```ts title="App.tsx"
222223
import "./App.css";
223224
import { generateClient } from "aws-amplify/api";
@@ -267,4 +268,53 @@ function App() {
267268

268269
export default App;
269270
```
271+
</InlineFilter>
270272

273+
<InlineFilter filters={["angular"]}>
274+
```ts title="app.component.ts"
275+
import type { Schema } from '../../../amplify/data/resource';
276+
import { Component } from '@angular/core';
277+
import { generateClient } from 'aws-amplify/api';
278+
import { getUrl } from 'aws-amplify/storage';
279+
280+
const client = generateClient<Schema>();
281+
282+
type PollyReturnType = Schema['convertTextToSpeech']['returnType'];
283+
284+
@Component({
285+
selector: 'app-root',
286+
template: `
287+
<div class="flex flex-col">
288+
<button (click)="synthesize()">Synth</button>
289+
<button (click)="fetchAudio()">Fetch audio</button>
290+
<a [href]="src">Get audio file</a>
291+
</div>
292+
`,
293+
styleUrls: ['./app.component.css'],
294+
})
295+
export class App {
296+
src: string = '';
297+
file: PollyReturnType = '';
298+
299+
async synthesize() {
300+
const { data, errors } = await client.mutations.convertTextToSpeech({
301+
text: 'Hello World!',
302+
});
303+
304+
if (!errors && data) {
305+
this.file = data;
306+
} else {
307+
console.log(errors);
308+
}
309+
}
310+
311+
async fetchAudio() {
312+
const res = await getUrl({
313+
path: 'public/' + this.file,
314+
});
315+
316+
this.src = res.url.toString();
317+
}
318+
}
319+
```
320+
</InlineFilter>

src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-amazon-rekognition/index.mdx

+69
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ Amplify.configure(outputs);
219219

220220
This code sets up a React app to upload an image to an S3 bucket and then use Amazon Rekognition to recognize the text in the uploaded image.
221221

222+
<InlineFilter filters={["react", "javascript", "nextjs", "react-native"]}>
222223
```ts title="App.tsx"
223224
import { type ChangeEvent, useState } from "react";
224225
import { generateClient } from "aws-amplify/api";
@@ -282,3 +283,71 @@ function App() {
282283

283284
export default App;
284285
```
286+
</InlineFilter>
287+
<InlineFilter filters={["angular"]}>
288+
```ts title="app.component.ts"
289+
import type { Schema } from '../../../amplify/data/resource';
290+
import { Component } from '@angular/core';
291+
import { generateClient } from 'aws-amplify/api';
292+
import { uploadData } from 'aws-amplify/storage';
293+
import { CommonModule } from '@angular/common';
294+
295+
// Generating the client
296+
const client = generateClient<Schema>();
297+
298+
type IdentifyTextReturnType = Schema['identifyText']['returnType'];
299+
300+
@Component({
301+
selector: 'app-text-recognition',
302+
standalone: true,
303+
imports: [CommonModule],
304+
template: `
305+
<div>
306+
<h1>Amazon Rekognition Text Recognition</h1>
307+
<div>
308+
<input type="file" (change)="handleTranslate($event)" />
309+
<button (click)="recognizeText()">Recognize Text</button>
310+
<div>
311+
<h3>Recognized Text:</h3>
312+
{{ textData }}
313+
</div>
314+
</div>
315+
</div>
316+
`,
317+
})
318+
export class TodosComponent {
319+
// Component properties instead of React state
320+
path: string = '';
321+
textData?: IdentifyTextReturnType;
322+
323+
// Function to handle file upload to S3 bucket
324+
async handleTranslate(event: Event) {
325+
const target = event.target as HTMLInputElement;
326+
if (target.files && target.files.length > 0) {
327+
const file = target.files[0];
328+
const s3Path = 'public/' + file.name;
329+
330+
try {
331+
await uploadData({
332+
path: s3Path,
333+
data: file,
334+
});
335+
336+
this.path = s3Path;
337+
} catch (error) {
338+
console.error(error);
339+
}
340+
}
341+
}
342+
343+
// Function to recognize text from the uploaded image
344+
async recognizeText() {
345+
// Identifying text in the uploaded image
346+
const { data } = await client.queries.identifyText({
347+
path: this.path, // File name
348+
});
349+
this.textData = data;
350+
}
351+
}
352+
```
353+
</InlineFilter>

src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-bedrock/index.mdx

+60
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ const { data, errors } = await client.queries.generateHaiku({
350350

351351
Here's an example of a simple UI that prompts a generative AI model to create a haiku based on user input:
352352

353+
<InlineFilter filters={["react", "javascript", "nextjs", "react-native", "vue"]}>
353354
```tsx title="App.tsx"
354355
import type { Schema } from '@/amplify/data/resource';
355356
import type { FormEvent } from 'react';
@@ -402,6 +403,65 @@ export default function App() {
402403
);
403404
}
404405
```
406+
</InlineFilter>
407+
408+
<InlineFilter filters={['angular']}>
409+
```ts title="app.component.ts"
410+
import type { Schema } from '../../../amplify/data/resource';
411+
import { Component } from '@angular/core';
412+
import { FormsModule } from '@angular/forms';
413+
import { Amplify } from 'aws-amplify';
414+
import { generateClient } from 'aws-amplify/api';
415+
import outputs from '../../../amplify_outputs.json';
416+
417+
Amplify.configure(outputs);
418+
419+
const client = generateClient<Schema>();
420+
421+
@Component({
422+
selector: 'app-haiku',
423+
standalone: true,
424+
imports: [FormsModule],
425+
template: `
426+
<main
427+
class="flex min-h-screen flex-col items-center justify-center p-24 dark:text-white"
428+
>
429+
<div>
430+
<h1 class="text-3xl font-bold text-center mb-4">Haiku Generator</h1>
431+
<form class="mb-4 self-center max-w-[500px]" (ngSubmit)="sendPrompt()">
432+
<input
433+
class="text-black p-2 w-full"
434+
placeholder="Enter a prompt..."
435+
name="prompt"
436+
[(ngModel)]="prompt"
437+
/>
438+
</form>
439+
<div class="text-center">
440+
<pre>{{ answer }}</pre>
441+
</div>
442+
</div>
443+
</main>
444+
`,
445+
})
446+
export class HaikuComponent {
447+
prompt: string = '';
448+
answer: string | null = null;
449+
450+
async sendPrompt() {
451+
const { data, errors } = await client.queries.generateHaiku({
452+
prompt: this.prompt,
453+
});
454+
455+
if (!errors) {
456+
this.answer = data;
457+
this.prompt = '';
458+
} else {
459+
console.log(errors);
460+
}
461+
}
462+
}
463+
```
464+
</InlineFilter>
405465

406466
![A webpage titled "Haiku Generator" and input field. "Frank Herbert's Dune" is entered and submitted. Shortly after, a haiku is rendered to the page.](/images/haiku-generator.gif)
407467

src/pages/[platform]/build-a-backend/data/query-data/index.mdx

+102-1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ const {
147147
});
148148
```
149149

150+
<InlineFilter filters={["react", "javascript", "nextjs", "react-native"]}>
151+
150152
If you're building a React application, you can use the `usePagination` hook in Amplify UI to help with managing the pagination user experience.
151153

152154
```js
@@ -187,6 +189,8 @@ export const PaginationHasMorePagesExample = () => {
187189
};
188190
```
189191

192+
</InlineFilter>
193+
190194
<Callout>
191195

192196
**Limitations:**
@@ -214,7 +218,11 @@ const { data: blogWithSubsetOfData, errors } = await client.models.Blog.get(
214218

215219
## TypeScript type helpers for Amplify Data
216220

217-
When using TypeScript, you frequently need to specify data model types for type generics. For instance, with React's `useState`, you provide a type in TypeScript to ensure type-safety in your component code using the state. Use the `Schema["MODEL_NAME"]["type"]` pattern to get TypeScript types for the shapes of data models returned from the backend API. This allows you to get consumable TypeScript types for the shapes of the data model return values coming from the backend API.
221+
When using TypeScript, you frequently need to specify data model types for type generics.
222+
223+
<InlineFilter filters={["react", "javascript", "nextjs", "react-native"]}>
224+
225+
For instance, with React's `useState`, you provide a type in TypeScript to ensure type-safety in your component code using the state. Use the `Schema["MODEL_NAME"]["type"]` pattern to get TypeScript types for the shapes of data models returned from the backend API.
218226

219227
```ts
220228
import { type Schema } from '@/amplify/data/resource';
@@ -224,8 +232,21 @@ type Post = Schema['Post']['type'];
224232
const [posts, setPosts] = useState<Post[]>([]);
225233
```
226234

235+
</InlineFilter>
236+
237+
<InlineFilter filters={["angular", "vue"]}>
238+
239+
```ts
240+
import { type Schema } from '../../../amplify/data/resource';
241+
242+
type Post = Schema['Post']['type'];
243+
```
244+
245+
</InlineFilter>
246+
227247
You can combine the `Schema["MODEL_NAME"]["type"]` type with the `SelectionSet` helper type to describe the return type of API requests using the `selectionSet` parameter:
228248

249+
<InlineFilter filters={["react", "javascript", "nextjs", "react-native"]}>
229250
```ts
230251
import type { SelectionSet } from 'aws-amplify/data';
231252
import type { Schema } from '../amplify/data/resource';
@@ -245,6 +266,86 @@ const fetchPosts = async () => {
245266
}
246267
```
247268

269+
</InlineFilter>
270+
271+
<InlineFilter filters={['vue']}>
272+
```ts
273+
<script setup lang="ts">
274+
import type { Schema } from '../../../amplify/data/resource';
275+
import { ref, onMounted } from 'vue';
276+
import { generateClient, type SelectionSet } from 'aws-amplify/data';
277+
278+
const client = generateClient<Schema>();
279+
280+
const selectionSet = ['content', 'blog.author.*', 'comments.*'] as const;
281+
282+
type PostWithComments = SelectionSet<
283+
Schema['Post']['type'],
284+
typeof selectionSet
285+
>;
286+
287+
const posts = ref<PostWithComments[]>([]);
288+
289+
const fetchPosts = async (): Promise<void> => {
290+
const { data: postsWithComments } = await client.models.Post.list({
291+
selectionSet,
292+
});
293+
posts.value = postsWithComments;
294+
};
295+
296+
onMounted(() => {
297+
fetchPosts();
298+
});
299+
</script>
300+
301+
<template v-for="post in posts" :key="post.id">
302+
<li>{{ post.content }}</li>
303+
</template>
304+
```
305+
</InlineFilter>
306+
307+
<InlineFilter filters={["angular"]}>
308+
```ts
309+
import type { Schema } from '../../../amplify/data/resource';
310+
import { Component, OnInit } from '@angular/core';
311+
import { generateClient, type SelectionSet } from 'aws-amplify/data';
312+
import { CommonModule } from '@angular/common';
313+
314+
const client = generateClient<Schema>();
315+
316+
const selectionSet = ['content', 'blog.author.*', 'comments.*'] as const;
317+
318+
type PostWithComments = SelectionSet<
319+
Schema['Post']['type'],
320+
typeof selectionSet
321+
>;
322+
323+
@Component({
324+
selector: 'app-todos',
325+
standalone: true,
326+
imports: [CommonModule],
327+
templateUrl: './todos.component.html',
328+
styleUrls: ['./todos.component.css'],
329+
})
330+
export class TodosComponent implements OnInit {
331+
posts: PostWithComments[] = [];
332+
333+
constructor() {}
334+
335+
ngOnInit(): void {
336+
this.fetchPosts();
337+
}
338+
339+
async fetchPosts(): Promise<void> {
340+
const { data: postsWithComments } = await client.models.Post.list({
341+
selectionSet,
342+
});
343+
this.posts = postsWithComments;
344+
}
345+
}
346+
```
347+
</InlineFilter>
348+
248349
## Cancel read requests
249350

250351
You can cancel any query API request by calling `.cancel` on the query request promise that's returned by `.list(...)` or `.get(...)`.

0 commit comments

Comments
 (0)