AWS Amplify - updating a column in a DynamoDB - reactjs

I am trying to figure out how to update a colums in a Dynamo table, using the 'aws-amplify' API.
Without Amplify, (just using the AWS SDK), that could be done like this:
const docClient = new AWS.DynamoDB.DocumentClient();
let params = {
TableName:table,
Key:{
"year": year,
"title": title
},
UpdateExpression: "set info.rating = :r, info.plot=:p, info.actors=:a",
ExpressionAttributeValues:{
":r":5.5,
":p":"Everything happens all at once.",
":a":["Larry", "Moe", "Curly"]
},
ReturnValues:"UPDATED_NEW"
};
docClient.update(params, function(err, data) { ....
I set up a backend/api using the docs here to ( enable cloud API to do CRUD operations)
https://docs.aws.amazon.com/aws-mobile/latest/developerguide/web-access-databases.html
Everything works fine as far as 'put/get' methods that create new records,etc
import Amplify, { API } from 'aws-amplify';
....
const path = '/MyTable';
const newRecord = {.......}
const apiResponse = await API.put('MyTableCRUD', path, newRecord);
But there is so little documentation on more advanced techniques like the update above, that I don't know how if/how this can be achieved using Amplify.
Hoping someone has already done this!
Thank you

You can create a custom route in the cloud API of your database (which is usually located under awsmobilejs/backend/cloud-api/INSERT_TABLE_NAME). Unless you modified the cloud API of your database in the past, the main file where all of the routes of the API are specified should be awsmobilejs/backend/cloud-api/INSERT_TABLE_NAME/app.js, or in your case awsmobilejs/backend/cloud-api/MyTable/app.js.
For more information about creating custom routes in your cloud API and some examples, check out the example app's cloud API and the express API reference.

Related

A way to fetch Microsoft Graph locations with PnPJs

As stated above in the title I am currently facing issues fetching graph places with PnPJs, using the #pnp/graph graphfi factory interface in SPFx.
I am currently able to fetch data from my events via graphfi as can be seen below:
React.useEffect(() => {
graph = graphfi().using(SPFx(props.context));
getSpecificCalendar();
}, []);
const getSpecificCalendar = async () => {
await graph.me.events().then((e) => setCalendarEvent(e));
}
I have tried to get the places property from the graph object but to no avail. The only properties present are me and users but no option for places.
Esentially what I want to do is to graph.places. The conclusion I have come to is that #pnp/graph does not have any methods to get room data. Any ideas other than what I have tried above would be extremely helpful.
It looks like pnpjs does not have the /places endpoint implemented (yet). You could try using the built-in SPFx graph client for now. Something like:
const client = await props.context.msGraphClientFactory.getClient('3')
const response = await client.api('/places/......').get();
Alternatively, you could implement the /places endpoint yourself and submit a pull request for pnpjs :)

google cloud online glossary creation returning "empty resource name" error

I am following the EXACT steps indicated here
https://cloud.google.com/translate/docs/glossary#create-glossary
to create a online glossary.
I am getting the following error
madan#cloudshell:~ (focused-pipe-251317)$ ./rungcglossary
{
"error": {
"code": 400,
"message": "Empty resource name.; Resource type: glossary",
"status": "INVALID_ARGUMENT"
}
}
Here is the body of my request.json
{
"languageCodesSet": {
"languageCodes": ["en", "en-GB", "ru", "fr", "pt-BR", "pt-PT", "es"]
},
"inputConfig": {
"gcsSource": {
"inputUri": "gs://focused-pipe-251317-vcm/testgc.csv"
}
}
}
The inputUri path i copied from the google cloud bucket file URI box.
I am not able to understand what the issue is. All I know is something is wrong with the inputUri string.
Please help.
Thanks.
I am a Google Cloud Technical Support Representative and we know that, for the moment, there is an issue with the REST API which is on track. I tried to reproduce your situation and while trying to create the glossary using directly the API I got the same issue as you.
After that, I have tried to create the glossary programmatically using a HTTP Triggered Python Cloud Function and everything went just right. In this manner your API will be called with the Cloud Functions service account.
I will attach the code of my Python Cloud function:
from google.cloud import translate_v3beta1 as translate
def create_glossary(request):
request_json = request.get_json()
client = translate.TranslationServiceClient()
## Set your project name
project_id = 'your-project-id'
## Set your wished glossary-id
glossary_id = 'your-glossary-id'
## Set your location
location = 'your-location' # The location of the glossary
name = client.glossary_path(
project_id,
location,
glossary_id)
language_codes_set = translate.types.Glossary.LanguageCodesSet(
language_codes=['en', 'es'])
## SET YOUR BUCKET URI
gcs_source = translate.types.GcsSource(
input_uri='your-gcs-source-uri')
input_config = translate.types.GlossaryInputConfig(
gcs_source=gcs_source)
glossary = translate.types.Glossary(
name=name,
language_codes_set=language_codes_set,
input_config=input_config)
parent = client.location_path(project_id, location)
operation = client.create_glossary(parent=parent, glossary=glossary)
result = operation.result(timeout=90)
print('Created: {}'.format(result.name))
print('Input Uri: {}'.format(result.input_config.gcs_source.input_uri))
The requirements.txt should include the following dependencies:
google-cloud-translate==1.4.0
google-cloud-storage==1.14.0
Do not forget to modify the code with your parameters
Basically, I have just followed the same tutorial as you, but for Python and I used Cloud Functions. My guess is that you can use App Engine Standard, as well.This may be an issue regarding the service account that are used to call this API. In case this doesn´t work for you let me know and I will try to edit my comment.

access Alexa Session persistence from other service

I have a Alexa hosted skill. I am trying to find a way to access persistenceAdapter.S3PersistenceAdapter() from some other places ( e.g. angular 2.x). Can this be done, or I have to use other database to replace S3? If that is the case, which database is recommended?
I use some sample code to access S3 from alexa skill. I have no idea how attributesManager work, just copy and paste.
.withPersistenceAdapter(
new persistenceAdapter.S3PersistenceAdapter({bucketName:process.env.S3_PERSISTENCE_BUCKET})
)
and
const attributesManager = handlerInput.attributesManager;
const sessionAttributes = await attributesManager.getPersistentAttributes() || {};
const temperature = sessionAttributes.hasOwnProperty('temperature') ? sessionAttributes.temperature : 0;
S3 isn't a database - S3 is object storage. If a database is what you need, you could use DynamoDB instead. It sounds like it is - you wouldn't normally use S3 for this.
Anyway, you'll not be able to use the ASK SDK in an Angular or other (non Alexa skill) project. But, you could connect to S3 (or DynamoDB) using the AWS SDK.
https://github.com/aws/aws-sdk-js
You have 3x types of attributes for Alexa - request, session and persistent. I noticed your variable is named sessionAttributes but you're doing getPersistentAttributes.
Here's an example of how you'd use the withPersistentAdapter - https://www.talkingtocomputers.com/alexa-skills-kit-ask-sdk-v2#data-persistence
But here's an example if you use DynamoDB. It's simpler IMO:
module.exports.handler = Alexa.SkillBuilders.standard()
.addRequestHandlers(/* your handlers */)
.withTableName(/* your table name (string) */)
.withDynamoDbClient()
.lambda()
}
Then you could do something like (in an async function):
const att = await attributesManager.getPersistentAttributes()
const temperature = att.temperature ? att.temperature : 0
But of course, you need to save the attribute there first, if you want to access it. For example (in an async function):
const att = await attributesManager.getPersistentAttributes()
await attributesManager.setPersistentAttributes( { ...att, temperature: 10 }) // set the value
await attributesManager.savePersistentAttributes() // save it
You can use S3 buckets the syntax looks like this, they do have get,set and save like the persistence attributes as in the example above and more on this you can go here the Amazon Docs at the bottom.
const { S3PersistenceAdapter } = require('ask-sdk-s3-persistence-adapter');
const S3PersistenceAdapter = new S3PersistenceAdapter({ bucketName : 'FooBucket' })

React Native - How to connect to AWS DynamoDB table

I am following this aws tutorial to create my first React Native app which connects to AWS:
aws tutorial
Everything installs fine and my app runs happily with the following imports:
**import Amplify from 'aws-amplify';
import aws_exports from './aws-exports';
Amplify.configure(aws_exports);**
I would now like to connect the app to an existing DynamoDB table called 'Movement' but the tutorial only shows how to create a new table with the NoSQL wizard using: awsmobile database enable --prompt
Could you point me to a (simple) resource that shows me how to connect to an existing DynamoDB table and perform CRUD operations?
These are the steps I have followed:
I have a DynamoDB table called: movement
It has 3 items : hub_id, on_time, message
Hub_id is the primary partition key
on_time is the primary sort key
The table holds sensor data (movement, temperature that sort of thing) in the message item.
I created the app using :
create-react-native-app dbapp
I have then run:
awsmobile configure
aws mobile init
Installed amplify:
npm install aws-amplify --save
I created the project in mobile hub.
I then linked the app to the hub using:
awsmobile init 15c482e2-2c3c-11e8-8692-fblahblahblah3
CLI responded : Successfully linked AWS Mobile Hub project: dbapp-datetime!
So all looks good so far (I hope!)
I then altered app.js to look like this: pastebin
npm start runs just fine with no errors that I can see.
The problem that I currently have is that I don't have a clue about how to query my table and populate variables so that I can use them in the view.
Following the resources suggested (thanks SteveB). I connected to the DynamoDB table, queried it and used the data in my app.
In case you are also stuck, here is an edited version of my code. Apologies to everyone that gets to edit this - I know it is awful. Does work though :)
// Use db to query the dynamoDB table - setup query parameters first //
var params = {
TableName : "myproject-mobilehub-123456789-Sensors",
ProjectionExpression:"hub_id, details.on_time, details.sensor_name,
details.temperature, details.battery",
KeyConditionExpression: "hub_id = :hid AND begins_with(on_time, :d)",
ExpressionAttributeValues: {
":hid":"testdevice01",
":d": today,
},
Limit: 1,
ScanIndexForward: false
};
//Execute db query using params
async getQuery() {
db.query(params, function(err, data) {
if (err) { console.log("Query failed.");
} else {
console.log("Query succeeded.");
};
data.Items.forEach(function(details) {
//display variables
console.log(details.hub_id,details.details.sensor_name,details.details.on_time,
details.details.temperature, details.details.battery,);
//Populate variables
hubid = details.hub_id;
currroom = details.details.sensor_name;
roomtime = details.details.on_time;
roomtemp = details.details.temperature;
roombattery = details.details.battery + "%";
});
}});
//Finally populate text with variables
this.setState({
displayText1: currroom,
displayText2: roombattery,
displayText3: roomtime,
displayText4: roomtemp
});

using the googleapis library in dart to update a calendar and display it on a webpage

I am new to dart and I have been trying to figure out how to use the googleapis library to update a calendars events, then display the calendar/events on a webpage.
So far I have this code that I was hoping would just change the #text id's text to a list of events from the selected calendars ID:
import 'dart:html';
import 'package:googleapis/calendar/v3.dart';
import 'package:googleapis_auth/auth_io.dart';
final _credentials = new ServiceAccountCredentials.fromJson(r'''
{
"private_key_id": "myprivatekeyid",
"private_key": "myprivatekey",
"client_email": "myclientemail",
"client_id": "myclientid",
"type": "service_account"
}
''');
const _SCOPES = const [CalendarApi.CalendarScope];
void main() {
clientViaServiceAccount(_credentials, _SCOPES).then((http_client) {
var calendar = new CalendarApi(http_client);
String adminPanelCalendarId = 'mycalendarID';
var event = calendar.events;
var events = event.list(adminPanelCalendarId);
events.then((showEvents) {
querySelector("#text2").text = showEvents.toString();
});
});
}
But nothing displays on the webpage. I think I am misunderstanding how to use client-side and server-side code in dart... Do I break up the file into multiple files? How would I go about updating a calendar and displaying it on a web page with dart?
I'm familiar with the browser package, but this is the first time I have written anything with server-side libraries(googleapis uses dart:io so I assume it's server-side? I cannot run the code in dartium).
If anybody could point me in the right direction, or provide an example as to how this could be accomplished, I would really appreciate it!
What you might be looking for is the hybrid flow. This produces two items
access credentials (for client side API access)
authorization code (for server side API access using the user credentials)
From the documentation:
Use case: A web application might want to get consent for accessing data on behalf of a user. The client part is a dynamic webapp which wants to open a popup which asks the user for consent. The webapp might want to use the credentials to make API calls, but the server may want to have offline access to user data as well.
The page Google+ Sign-In for server-side apps describes how this flow works.
Using the following code you can display the events of a calendar associated with the logged account. In this example i used createImplicitBrowserFlow ( see the documentation at https://pub.dartlang.org/packages/googleapis_auth ) with id and key from Google Cloud Console Project.
import 'dart:html';
import 'package:googleapis/calendar/v3.dart';
import 'package:googleapis_auth/auth_browser.dart' as auth;
var id = new auth.ClientId("<yourID>", "<yourKey>");
var scopes = [CalendarApi.CalendarScope];
void main() {
auth.createImplicitBrowserFlow(id, scopes).then((auth.BrowserOAuth2Flow flow) {
flow.clientViaUserConsent().then((auth.AuthClient client) {
var calendar = new CalendarApi(client);
String adminPanelCalendarId = 'primary';
var event = calendar.events;
var events = event.list(adminPanelCalendarId);
events.then((showEvents) {
showEvents.items.forEach((Event ev) { print(ev.summary); });
querySelector("#text2").text = showEvents.toString();
});
client.close();
flow.close();
});
});
}

Resources