React Tutorialを初めてやったとき勘違いしてたことメモ

なんで上書きされないの?

 render() {
        const status = 'Next player: X';

        return (
            <div>
                <div className="status">{status}</div>
                <div className="board-row">
                    {this.renderSquare(0)}
                    {this.renderSquare(1)}//なんで一つ前の0を上書きしない??
                    {this.renderSquare(2)}
                </div>
                <div className="board-row">
                    {this.renderSquare(3)}
                    {this.renderSquare(4)}
                    {this.renderSquare(5)}
                </div>
                <div className="board-row">
                    {this.renderSquare(6)}
                    {this.renderSquare(7)}
                    {this.renderSquare(8)}
                </div>
            </div>
        );
    }

→関数を呼んでいるから、上書きするわけではなく1を入れたときの結果が入るという話。

なんで多次元配列になってる?(なってない)

[
  'O', null, 'X',
  'X', 'X', 'O',
  'O', null, null,
]
//急にどうして多次元配列にできてるの?

なってない。多次元配列だとすると以下のようになる

[
  ['O', null, 'X'],
  ['X', 'X', 'O'],
  ['O', null, null]
]

なんでrender()内で定義するの?

  render() {
    const history = this.state.history; //render()の上でも良くない?
    const current = history[history.length - 1];
    const winner = calculateWinner(current.squares);
    let status;
    if (winner) {
      status = 'Winner: ' + winner;
    } else {
      status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
    }

    return (
      <div className="game">
        <div className="game-board">
          <Board
            squares={current.squares}
            onClick={(i) => this.handleClick(i)}
          />
        </div>
        <div className="game-info">
          <div>{status}</div>
          <ol>{/* TODO */}</ol>
        </div>
      </div>
    );
  }

Classの中はメゾットしか書けないとのことでした。

これなに?(三項演算子)

    const moves = history.map((step, move) => {
      const desc = move ?    // ? ???
        'Go to move #' + move : // : ???
        'Go to game start';
      return (
        <li>
          <button onClick={() => this.jumpTo(move)}>{desc}</button>
        </li>
      );
    });

条件式 ? Trueの処理 : Falseの処理

https://www.sejuku.net/blog/23627

実行結果を見ると分かりますが、JavaScriptでは「null」「undefined」を条件式に当てはめるといずれも「False」と判断されてしまいます。

https://www.sejuku.net/blog/23627

つまり、history,最初の時にはnullでfalseとなるのでGo to game startとなるということでした。

Posted By :
Comment :0

amplify initでAccessDeniedで1日飛んだ話

問題

amplifyで知り合いが開発しているものをcloneしてセットアップしていたところamplify initでこける

⠹ Initializing your environment: dev(node:80382) UnhandledPromiseRejectionWarning: AccessDenied: Access Denied

https://xp-cloud.jp/blog/2020/03/24/6922/

いろいろ参考になりそうな記事がるけれども、動かない。

amplify configureでいくつかIAM作り直したり、aws configureでaws cliのログインをしなおしてもダメ。

結論

credentialのdefaultをいじった

https://xp-cloud.jp/blog/2020/03/24/6922/

こちらの記事にある通り、amplify configで作ったプロファイルはdefaultとは別に指定した名前で~/.aws/credentialsに格納されてます。

で、どうやらamplify configでIAM作ってもamplify initする時はdefaultの方を参照してしまうらしく、それでAccess Deniedされていたみたいです。

なのであまり根本的に無解決になってない気がしますがdefaultを新たに作ったconfig情報で上書きしました。

もっといい解決法があればコメントいただけると嬉しいです。

cover Photo by Kai Oberhäuser on Unsplash

Posted By :
Comment :0

2つの配列で共通している物を削除したい-javascript

a = [1,2,3,4]
b = [3,4]

//なんとかして

c = [1,2]

//を得たい

filterとindexOfを組み合わせてできます。

let c = a.filter(n => b.indexOf(n) === -1);

追記

友人のプロにこっちの方がと指摘を受けました。

const a = [1, 2, 3, 4]
const b = [2, 3]

a.filter(elem => !b.includes(elem))
Posted By :
Comment :0

hubspotAPIのCreate a new contact をGASから叩いてみる

Google Spreadsheetの顧客リストからhubspotのcontactを作ろうとしていて、hubspotAPIを使ってみている。

hubspotは本当にありとあらゆるものがAPIとして用意されている。Contactを作るものはこれ

https://developers.hubspot.com/docs/methods/contacts/create_contact

node.jsだと

var request = require("request");

var options = { method: 'POST',
  url: 'https://api.hubapi.com/contacts/v1/contact/',
  qs: { hapikey: 'demo' },
  headers: 
   { 
     'Content-Type': 'application/json' },
  body: 
   { properties: 
      [ { property: 'email', value: 'testingapis@hubspot.com' },
        { property: 'firstname', value: 'test' },
        { property: 'lastname', value: 'testerson' },
        { property: 'website', value: 'http://hubspot.com' },
        { property: 'company', value: 'HubSpot' },
        { property: 'phone', value: '555-122-2323' },
        { property: 'address', value: '25 First Street' },
        { property: 'city', value: 'Cambridge' },
        { property: 'state', value: 'MA' },
        { property: 'zip', value: '02139' } ] },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

となる。GASの方のサンプルはこれ

https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app

// Make a POST request with a JSON payload.
var data = {
  'name': 'Bob Smith',
  'age': 35,
  'pets': ['fido', 'fluffy']
};
var options = {
  'method' : 'post',
  'contentType': 'application/json',
  // Convert the JavaScript object to a JSON string.
  'payload' : JSON.stringify(data)
};
UrlFetchApp.fetch('https://httpbin.org/post', options);

node.jsの方はAPIキーをqsのオプションで足しているのでそれをとりあえずURLにベタうち

function postHubspot(text){
  
  
  
  // Make a POST request with a JSON payload.
var data = {
  'properties': 
      [ { property: 'email', value: 'testingapis@hubspot.com' },
        { property: 'firstname', value: 'test' },
        { property: 'lastname', value: 'testerson' },
        { property: 'website', value: 'http://hubspot.com' },
        { property: 'company', value: 'HubSpot' },
        { property: 'phone', value: '555-122-2323' },
        { property: 'address', value: '25 First Street' },
        { property: 'city', value: 'Cambridge' },
        { property: 'state', value: 'MA' },
        { property: 'zip', value: '02139' } ], 

  'json': true  
};


var options = {
  'method' : 'post',
  'contentType': 'application/json',
  // Convert the JavaScript object to a JSON string.
  'payload' : JSON.stringify(data)
};

UrlFetchApp.fetch('https://api.hubapi.com/contacts/v1/contact/?hapikey="hubspotのAPIキー"', options);
  

};

これでとりあえず作成はできました。

Posted By :
Comment :0

react-navigationでScreen内容を別ファイルにする

React-nativeでNavigationを使って画面遷移をする時

https://reactnavigation.org/docs/hello-react-navigation/

サンプルプログラムでは1つのファイルに遷移先含めて入れている。

import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}

function DetailsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Button
        title="Go to Details... again"
        onPress={() => navigation.push('Details')}
      />
      <Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
      <Button title="Go back" onPress={() => navigation.goBack()} />
      <Button
        title="Go back to first screen in stack"
        onPress={() => navigation.popToTop()}
      />
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

ページ数が増えてきたり複雑になってきたりすることを想定して別スクリーンの内容は別ファイルにしたい。

フォルダを作る

適当にページを入れるフォルダを作ります

import文を書く

import HomeScreen from "./pages/Home"
import DetailScreen from "./pages/Details"

Stack.ScreenのあるApp.jsでそれぞれのcomponentを先ほど置いたpagesの中身から取るようにimport文を書きます。

pagesの中にimportに対応するjsファイルを作ります。

それぞれにページの内容を記述します

import * as React from 'react';
import { View, Text, Button } from 'react-native';


export default ({route, navigation}) => {

    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>Home Screen</Text>
            <Button
                title="Go to Details... again"
                onPress={() => navigation.push('Detail')}
            />
        </View>
    );


}

値を渡す場合も一つのコードの中で書いてた時と同じように

<Button onPress={ ()=> navigation.navigate("Individual",{
    content: elem.jobDetail,
    id: elem.id,
    done: elem.done
 })} title={""}/>

と言う形で渡せば

route.id

のような形で受け取れます。

Posted By :
Comment :0

初めてFirebaseをexpo使いながら触ろうとした時databaseのrulesが見つからなかった

Firebase一度触ってみたいと言うことで

https://docs.expo.io/guides/using-firebase/

ここをやり始めたところいきなり

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

データベースのルールをみようと言うことでコンソールに行ってみると

なんか全然形式が違う気がする。。。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

いろいろ調べててもよくわからずいろいろいじっていると

なんか2種類ある。作る時選択するところがあったのかもしれませんが、全然気がつきませんでした。

https://firebase.google.com/docs/database/rtdb-vs-firestore?hl=ja

Cloud Firestore は、Firebase のモバイルアプリ開発用の最新データベースです。直感的な新しいデータモデルで Realtime Database をさらに強化しています。Cloud Firestore は、Realtime Database よりも多彩で高速なクエリと高性能なスケーリングが特長です。

Realtime Database は従来からある Firebase のデータベースです。リアルタイムのクライアント間同期が必要なモバイルアプリのための、効率的でレイテンシが低いソリューションです。

新しいのができたみたいで、ドキュメントが古かったってことみたいです。

気がつかなかった。。。

Posted By :
Comment :0