Using AWS SDK (JS) for s3.selectObjectContent gives error on 'on' keyword - amazon-s3

I'm using AWS SDK for Javascript version 2.730.0 (latest at time of writing) in a Typescript file in Node.JS.
I'm using the selectObjectContent operation to query a CSV file, and following the guide in the documentation I have this block:
import * as S3 from 'aws-sdk/clients/s3';
const s3 = new S3();
...
s3.selectObjectContent(params, (err, data) => {
if (!err){
data.Payload.on('data', (event) => {
// Do something with returned records
});
}
});
The line data.Payload.on('data', (event) => { is giving this error in the linter:
Property 'on' does not exist on type 'EventStream<{ Records?: RecordsEvent; Stats?: StatsEvent; Progress?: ProgressEvent; Cont?: ContinuationEvent; End?: EndEvent; }>'.
What do I need to change for on to work?

I ran into the same problem myself. Found this problem post on another forum:
https://www.gitmemory.com/issue/aws/aws-sdk-js/3525/725076849
It does not explicitly show code to solve the problem but based on the information, I solved it as follows:
import { ReadStream } from "fs";
const eventStream = data.Payload as ReadStream;
eventStream.on("data", ({ Records, Stats, Progress, Cont, End }: ...
TypeScript no longer complains.

Related

"The original argument must be of type function" ERROR for promisifying client.zrem?

I am making a cron job instance that is running using Node to run a job that removes posts from my Redis cache.
I want to promisify client.zrem for removing many posts from the cache to insure they are all removed but when running my code I get the error below on line: "client.zrem = util.promisify(client.zrem)"
"TypeError [ERR_INVALID_ARG_TYPE]: The "original" argument must be of type function. Received undefined"
I have another Node instance that runs this SAME CODE with no errors, and I have updated my NPM version to the latest version, according to a similar question for this SO article but I am still getting the error.
TypeError [ERR_INVALID_ARG_TYPE]: The "original" argument must be of type Function. Received type undefined
Any idea how I can fix this?
const Redis = require("redis")
const util = require(`util`)
const client = Redis.createClient({
url: process.env.REDIS,
})
client.zrem = util.promisify(client.zrem) // ERROR THROWN HERE
// DELETE ONE POST
const deletePost = async (deletedPost) => {
await client.zrem("posts", JSON.stringify(deletedPost))
}
// DELETES MANY POSTS
const deleteManyPosts = (postsToDelete) => {
postsToDelete.map(async (post) => {
await client.zrem("posts", JSON.stringify(post))
})
}
module.exports = { deletePost, deleteManyPosts }
Node Redis 4.x introduced several breaking changes. Adding support for Promises was one of those. Renaming the methods to be camel cased was another. Details can be found at in the README in the GitHub repo for Node Redis.
You need to simply delete the offending line and rename the calls to .zrem to .zRem.
I've also noticed that you aren't explicitly connecting to Redis after creating the client. You'll want to do that.
Try this:
const Redis = require("redis")
const client = Redis.createClient({
url: process.env.REDIS,
})
// CONNECT TO REDIS
// NOTE: this code assumes that the Node.js version supports top-level await
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect(); //
// DELETE ONE POST
const deletePost = async (deletedPost) => {
await client.zRem("posts", JSON.stringify(deletedPost))
}
// DELETES MANY POSTS
const deleteManyPosts = (postsToDelete) => {
postsToDelete.map(async (post) => {
await client.zRem("posts", JSON.stringify(post))
})
}
module.exports = { deletePost, deleteManyPosts }

Storage.put() throwing - AWSS3Provider - error uploading TypeError: Cannot read property 'byteLength' of undefined

JavaScript Framework (Vue)
Amplify APIs (Storage)
Amplify Categories (storage)
Getting Cannot read property 'byteLength' of undefined while uploading media to s3 bucket using amplify storage, below is the code I am currently using
async onUpload(fileArr) {
if (fileArr.length > 0) {
console.log("fileArr", fileArr);
fileArr.map(async (obj) => {
try {
console.log({ Storage, Amplify });
console.log("Object =>", obj);
let baseData = await this.toBase64(obj);
console.log("Base Data =>", baseData);
const arrayBuffer = decode(baseData);
console.log("Array buffer =>", arrayBuffer);
let result = await Storage.put(
`hub/${obj.name}`,
arrayBuffer,
{
contentType: obj.type,
}
);
console.log("S3 Upload Result =>", result);
} catch (err) {
console.log("Error in uploading", err);
}
});
}
},
I tried to convert media to base64 before uploading but still getting same error
ERROR OUTPUT
Error - AWSS3Provider - error uploading TypeError: Cannot read property 'byteLength' of undefined
I granted full access to my IAM user and role but it didn't work either, I looked for multiple solution available online but still I didn't make it out.
I also faced this problem while uploading data to s3 using Apmplify.
The problem is not in your code its library version issue, make sure to use same Amplify version which is used on server
Latest Amplify version is 4.3.0
https://www.npmjs.com/package/aws-amplify

How to update an object stored in Realm using React Native

Recently I keep running into several problems when trying to write data to my realm instance. The error I keep running into is the following:
Possible Unhandled Promise Rejection (id: 0): Error: Cannot modify
managed objects outside of a write transaction.
Despite my "changes" being done within a write transaction. I've looked at the official docs of Realm for doing writes. But it keeps running into the message above. So things I tried in order to write to solve this issue:
update to the latest version of the library in my project I now am at 6.0.2
Using the solution below:
Realm.open({
path: 'database.realm',
schema: this.modelSchema,
schemaVersion: 3,
}).then(realm => {
realm.write(() => {
realm.create('RouteType', {typeID: element.typeID, isSelected: !element.isSelected}, true);
});
});
And another method I used with the same result is this one:
try {
realm.write(() => {
realm.create(
'RouteType',
{typeID: element.typeID, isSelected: !element.isSelected}, true,);
});
} catch (e) {
console.log(e);
}

Input form provides File - how to I upload it to Azure Blob storage using Vue?

I'm clearly missing something here so forgive me - all examples seem to involve express and I don't have express in my setup. I am using Vue.js.
Ultimately, want my client-side Vue app to be able to upload any file to azure blob storage.
I have the file(File api) from my Vue form. However, it does not provide a path (I believe this is for security reasons). The Azure docs have this snippet example:
const uploadLocalFile = async (containerName, filePath) => {
return new Promise((resolve, reject) => {
const fullPath = path.resolve(filePath);
const blobName = path.basename(filePath);
blobService.createBlockBlobFromLocalFile(containerName, blobName, fullPath, err => {
if (err) {
reject(err);
} else {
resolve({ message: `Local file "${filePath}" is uploaded` });
}
});
});
};
Is this not the api I should be using? What should I be doing to upload any type of blob to blob storage?
UPDATE
Following #Adam Smith-MSFT comments below I have tried the vue-azure-storage-upload but can't seem to get the files up to azure.
startUpload () {
if (!this.files || !this.baseUrl) {
window.alert('Provide proper data first!')
} else {
this.files.forEach((file:File) => {
this.$azureUpload({
baseUrl: this.baseUrl + file.name,
sasToken: this.sasToken,
file: file,
progress: this.onProgress,
complete: this.onComplete,
error: this.onError
// blockSize
})
})
}
},
According to the console the response.data is undefined and when the onError method fires, that too gives me an undefined event.
I'd highly recommend checking the following tutorial: https://www.npmjs.com/package/vue-azure-blob-upload
The author used a specific npm package to upload blobs(you can using file service) to upload objects:
npm i --save vue-azure-blob-upload
I'd also recommend checking the Storage JS documentation: https://github.com/Azure/azure-storage-js/tree/master/file , it provides specific examples related to Azure File Storage as well.

Upload images with apollo-upload-client in React Native

I'm trying out Prisma and React Native right now. Currently I'm trying to upload images to my db with the package _apollo-upload-client (https://github.com/jaydenseric/apollo-upload-client). But it's not going so well.
Currently I can select an image with the ImagePicker from Expo. And then I'm trying to do my mutation with the Apollo Client:
await this.props.mutate({
variables: {
name,
description,
price,
image,
},
});
But I get the following error:
Network error: JSON Parse error: Unexpected identifier "POST"
- node_modules/apollo-client/bundle.umd.js:76:32 in ApolloError
- node_modules/apollo-client/bundle.umd.js:797:43 in error
And I believe it's from these lines of code:
const image = new ReactNativeFile({
uri: imageUrl,
type: 'image/png',
name: 'i-am-a-name',
});
Which is almost identical from the their example, https://github.com/jaydenseric/apollo-upload-client#react-native.
imageUrl is from my state. And when I console.log image I get the following:
ReactNativeFile {
"name": "i-am-a-name",
"type": "image/png",
"uri": "file:///Users/martinnord/Library/Developer/CoreSimulator/Devices/4C297288-A876-4159-9CD7-41D75303D07F/data/Containers/Data/Application/8E899238-DE52-47BF-99E2-583717740E40/Library/Caches/ExponentExperienceData/%2540anonymous%252Fecommerce-app-e5eacce4-b22c-4ab9-9151-55cd82ba58bf/ImagePicker/771798A4-84F1-4130-AB37-9F382546AE47.png",
}
So something is popping out. But I can't get any further and I'm hoping I could get some tips from someone.
I also didn't include any code from the backend since I believe the problem lays on the frontend. But if anyone would like to take a look at the backend I can update the question, or you could take a look here: https://github.com/Martinnord/Ecommerce-server/tree/image_uploads.
Thanks a lot for reading! Cheers.
Update
After someone asked after the logic in the server I have decided to past it below:
Product.ts
// import shortid from 'shortid'
import { createWriteStream } from 'fs'
import { getUserId, Context } from '../../utils'
const storeUpload = async ({ stream, filename }): Promise<any> => {
// const path = `images/${shortid.generate()}`
const path = `images/test`
return new Promise((resolve, reject) =>
stream
.pipe(createWriteStream(path))
.on('finish', () => resolve({ path }))
.on('error', reject),
)
}
const processUpload = async upload => {
const { stream, filename, mimetype, encoding } = await upload
const { path } = await storeUpload({ stream, filename })
return path
}
export const product = {
async createProduct(parent, { name, description, price, image }, ctx: Context, info) {
// const userId = getUserId(ctx)
const userId = 1;
console.log(image);
const imageUrl = await processUpload(image);
console.log(imageUrl);
return ctx.db.mutation.createProduct(
{
data: {
name,
description,
price,
imageUrl,
seller: {
connect: { id: userId },
},
},
},
info
)
},
}
Solution has been found.
I am a little embarrassed that this was the problem that I faced and I don't know if I should even accept this answer because of awkward I felt when I fixed the issue. But....
There was nothing wrong with my code, but there was a problem with the dependencies versions. I tried to backtrack everything on my app, so I decided to start from the beginning and create a new account. I expected it to work just fine, but I got this error:
Error: Cannot use GraphQLNonNull "User!" from another module or realm.
Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.
https://yarnpkg.com/en/docs/selective-version-resolutions
Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.
Then I understand that something (that I didn't think of) was wrong. I checked my dependencies versions and compared them with Graphcool's example, https://github.com/graphcool/graphql-server-example/blob/master/package.json. And I noticed that my dependencies was outdated. So I upgraded them and everything worked! So that was what I had to do. Update my dependencies.
Moral of the story
Always, always check your damn dependencies versions...
Crawling through your code, I have found this repository, which must be the front-end code if I am not mistaken?
As you've mentioned, apollo-upload-server requires some additional set-up and same goes for the front-end part of your project. You can find more about it here.
As far as I know, the problematic part of your code must be the initialisation of the Apollo Client. From my observation, you've put everything Apollo requires inside of src/index folder, but haven't included Apollo Upload Client itself.
I have created a gist from one of my projects which initialises Apollo Upload Client alongside some other things, but I think you'll find yourself out.
https://gist.github.com/maticzav/86892448682f40e0bc9fc4d4a3acd93a
Hope this helps you! 🙂