81147


こちらのサイトを参考にReact.jsを用いてS3のリストを取得するスクリプトを作成しております。  
<https://note.kiriukun.com/entry/20190419-s3-examples-list-objects-in-node>

npm startで先ほど動作を確認したところ、タイトルのエラーに引っかかってしまい、直せない状況です。  
App.jsの内容は以下の通りです。  
JavaScriptはあまり触ってこなかったので初歩的な質問となっているかもしれませんが、どうぞ宜しくお願い致します。

[code]

    import Amplify, { Storage } from 'aws-amplify';
    import { AmplifyAuthenticator, AmplifySignUp, AmplifySignOut } from '@aws-amplify/ui-react';
    import { AuthState, onAuthUIStateChange } from '@aws-amplify/ui-components';
    import awsconfig from './aws-exports';
    import aws from 'aws-sdk';
    import { Bucket } from '@aws-sdk/client-s3';
    
    Amplify.configure(awsconfig);
    
    const App = () => {
        const [name, setName] = useState('')
        const [file, setFile] = useState('')
        const [response, setResponse] = useState('')
    
        const [authState, setAuthState] = React.useState();
        const [user, setUser] = React.useState();
    
        React.useEffect(() => {
            return onAuthUIStateChange((nextAuthState, authData) => {
                setAuthState(nextAuthState);
                setUser(authData)
            });
        }, []);
    
        const onChange = (e) => {
        e.preventDefault()
        if (e.target.files[0] !== null) {
          setFile(e.target.files[0])
          setName(e.target.files[0].name)
        }
      }
    
      const onSubmit = (e) => {
        e.preventDefault()
        if (file) {
          Storage.put(name, file, {
            /* level: 'protected', */
            contentType: file.type,
          })
            .then((result) => {
              console.log(result)
              setResponse(`Success uploading file: ${name}!`)
            })
            .then(() => {
              document.getElementById('file-input').value = null
              setFile(null)
            })
            .catch((err) => {
              console.log(err)
              setResponse(`Can't upload file: ${err}`)
            })
        } else {
          setResponse(`Files needed!`)
        }
      }
    
      aws.config.update({   
        region: 'ap-northeast-1',  // ここでは東京リージョンを入力
      });
      var s3 = new aws.S3();
      let keyList = [];
        for (let continuationToken = null;;) {
            // パラメータ作成
            const params = {
                Bucket: 'sample',  // バケット名
            };
            if (continuationToken) {
                // 読み込み開始位置 (ContinuationToken) がある場合はパラメータに追加
                params.ContinuationToken = continuationToken;
            }
            
            // オブジェクトのリストを取得
            const res = s3.listObjectsV2(params).promise();
            
            // オブジェクトキー (Key属性) だけ取り出してキーリストに追加
            res.Contents.map(v => v.Key).forEach(v => {
                keyList.push(v);
            });
            
            // listObjectsV2 が一度に取得できるのは1000件まで
            // リストが切り詰められている場合は IsTruncated がtrueになる
            if (!res.IsTruncated) {
                break;
            }
            
            // 次の読み込み開始位置を保存
            continuationToken = res.NextContinuationToken;
        }
        
        // 全てのオブジェクトを処理
        for (let key of keyList) {
            // オブジェクトを取得
            const res = s3.getObject({
                Bucket: 'sample',
                Key: key
            }).promise();
            
            // ファイル本文 (Buffer) をUTF-8でデコード
            const body = res.Body.toString('utf8');
            
            // 1行目だけコンソールに出力
            console.log(key + ' ->', body.split('\n')[0].trim());
        }
    
      return authState === AuthState.SignedIn && user ? (
          <div className="App">
              <div>Hello, {user.username}</div>
              <div className='video-uploader'>
                <form onSubmit={(e) => onSubmit(e)}>
                <p>
                  <label className='select-label'>Select video: </label>
                </p>
                <p>
                  <input
                    className='video-input'
                    type='file'
                    id='file-input'
                    accept='image/*, video/*'
                    onChange={(e) => onChange(e)}
                  />
                </p>
                <button type='submit' className='btn'>Submit</button>
              </form>
              </div>
              <AmplifySignOut />
          </div>
        ) : (
          <AmplifyAuthenticator>
            <AmplifySignUp
              slot="sign-up"
              formFields={[
                { type: "username" },
                { type: "password" },
                { type: "email" }
              ]}
            />
          </AmplifyAuthenticator>
      );
    }
    
    export default App;```
    
[/code]


CC BY-SA 4.0
2021-08-30T15:39:09.033
81126
2021-09-01T02:57:50.823
39728
question
javascript aws reactjs
TypeError: Cannot read property 'map' of undefined

[code]

    const res = s3.listObjectsV2(params).promise();
            
    // オブジェクトキー (Key属性) だけ取り出してキーリストに追加
    res.Contents.map(v => v.Key).forEach(v => {
         keyList.push(v);
    });
    
[/code]

resは正常な値が取得できてないから、res.Contentsも存在しないか予想のlistやarrayではないため、res.Contents.mapを使うと、「Cannot
read property 'map' of undefined」が出るはずです。

リンク元のコードは

[code]

    const res = await s3.listObjectsV2(params).promise();
    
[/code]

だけど、結果を取得完了するまでに待つために、awaitは省略しないように試してみてください。


CC BY-SA 4.0
2021-09-01T02:57:50.823
81147
2021-09-01T02:57:50.823
35698
81126
answer