Skip to main content

Posts

Showing posts from 2020

update Array with ES6 - findIndex - useMutation - update local state instead of cache

  const newAccount = { ... data . data . assignRole } const newAccounts = [... accounts ] const foundIndex = newAccounts . findIndex ( x => x . id === id ) newAccounts [ foundIndex ] = newAccount setAccounts ( newAccounts ) update local state instead of update the cache  const [ assignRole ] = useMutation ( MUTATION_ASSIGN_ROLE ) const handleSave = ( id : string , role : string ) => { const assignRoleInput = { id , role } assignRole ({ variables : { assignRoleInput }, }) . then (( data : any ) => { const newAccount = { ... data . data . assignRole } const newAccounts = [... accounts ] const foundIndex = newAccounts . findIndex ( x => x . id === id ) newAccounts [ foundIndex ] = newAccount setAccounts ( newAccounts ) }) . catch ( error => console . log ( error . message )) setOpenRolesDialog ( false ) }

fs.writeFile - permission issue on GCP (Google Cloud Run)

error on this: fs . writeFile ( fileName , pdfBytes , err => { if ( err ) { console . log ( err . message ) reject ( err . message ) } else resolve ( fileName ) }) #1 It looks like when deployed into Cloud Run it also requires the extra permission "Service Account Token Creator" to run  getSignedUrl . Locally for some reason this role is not required. #2 Only the directory  /tmp  is writable in Cloud Run. So, change the default write location to write into this directory. However, you have to be aware of 2 things: Cloud Run is stateless, that means when a new instance is created, the container start from scratch, with an empty  /tmp  directory /tmp  directory is an in-memory file system. The maximum allowed memory on Cloud Run is 2Gb, your app memory footprint included. In addition of your file and Airflow, not sure that you will have a lot of space. A final remark. Cloud Run is active only when it...

useLayoutEffect - useRef

  99% of the time you’re going to want to use the   useEffect  hook, and the   useState  hook to manipulate the output of a React component. But in certain cases you need make changes directly to a DOM node. In case you need to, follow these 2 rule of thumbs: Use  useRef  if you need to manage focus, text selection, trigger imperative animations or integrating third-party libraries. Use the  useLayoutEffect  when ever you need to use  useRef . https://linguinecode.com/post/when-to-use-useref-and-uselayouteffect

zip photos and download from react app -

library:  jszip -  const zip = jszip () file-saver -  saveAs ( content , ` ${ fetchListingId } .zip` ) issue: cors -  the original plan was download photos from the front end and zip with jszip, but got cors error when download from firebase storage solutions: 1. on graphql, add query:  getPhotosBuffer(listingId: String): [PhotoBuffer] to return stringified buffer of photos fetchPhotosBuffer = async ( listingId : string ): Promise < PhotoBuffer []> => this . cacheProvider . processor < PhotoBuffer []>( async () => { const photos = await this . collection . where ( 'listingId' , '==' , listingId ) . orderBy ( 'orders' ) . get () const result : PhotoBuffer [] = [] await Promise . all ( photos . docs . map ( async ( photo : any ) => { const data = photo . data () const { photoUrl } = data try { const bu...

keep re-render issue for custom hook - useEffect, fixed by useMemo to wrap object

solution is: for object, need wrap with useMemo in this case, if function, need wrap with useCallback const accountRoles = useMemo (() => account ?. roles || [], [])  issue was in listing.tsx const accountRoles = account ?. roles || [], [] const [ todoDocs ] = useListingTodoDocs ( listingId , accountRoles , false ) in useListingTodoDocs, ulilize useEffect to fetch data, acccountRoles is object, so always change and trigger useEffect action. useEffect (() => { const fetchListingTodos = async () => { const result = await client . query ({ query : GET_TODO_DOCUMENTS , variables : { listingId : listingId }, fetchPolicy : 'no-cache' , }) const { data : { getTodoDocuments }, } = result const filterTodosByRole = accountRoles . length === 0 ? getTodoDocuments . filter ( ( doc : Document ) => ! doc . name . includes ( LISTING_AGREEMENT_B...

missing dependency for useEffect/useCallback when call function from useContext

#issue 1 was missing dependency: "e mptyShoppingCart" const { emptyShoppingCart } = useContext ( CartContext ) useEffect (() => { if ( oobCode ) { setOrderId ( oobCode ) emptyShoppingCart () } }, [ oobCode ]) so change to fix: useEffect (() => { if ( oobCode ) { setOrderId ( oobCode ) emptyShoppingCart () } }, [ oobCode, emptyShoppingCart ]) now #issue 2 is rendered forever because emptyShoppingCart always re-create fix: useCallback const emptyShoppingCart = useCallback (() => { setShoppingCart ([]) setListingId ( '' ) }, [])

use Map instead of Array with sort

  const input = 'i wanter Cats and dogs.' const convert = ( input ) => { const arr = input . substring ( 0 , input . length - 1 ). split ( ' ' ) const result = new Map () arr . forEach ( item => { const key = item . length if ( result . has ( key )){ result . set ( item . length , result . get ( key ) + ' ' + item ) } else result . set ( item . length , item ) }) const sorted = new Map ([... result . entries ()]. sort ()) let sentense = '' const values = Array . from ( sorted . values ()) values . forEach (( value , i ) => { const word = value . toLowerCase () if ( i === 0 ) sentense = sentense . concat ( word . substring ( 0 , 1 ). toUpperCase ()). concat ( word . substring ( 1 )) else sentense = sentense . concat ( word ) if ( i === values . length - 1 ) ...

for loop in javascript - promise - .eslintrc for "for of"

the vast majority of cases  map ,  forEach ,  find  etc. can be used.  async function printFiles () { const files = await getFilePaths(); await Promise.all(files. map (async (file) => { const contents = await fs.readFile(file, 'utf8') console.log(contents) })); } const inventory = [ { name : 'apples' , quantity : 2 } , { name : 'bananas' , quantity : 0 } , { name : 'cherries' , quantity : 5 } ] ; const result = inventory . find ( ( { name } ) => name === 'cherries' ) ;   function getFirstMatching(array) { for (let item of array) { const result = heavyTransform(item); if (result) { return result; } } } Specifically this shuts down the whole no-restricted-syntax. If you want to cherry-pick, here is the current definition: 'no-restricted-syntax' : [ 'error' , { selector : 'ForInStatement' , message...

Closures in Javascript

function add ( num ) { var counter = 0 ; return function ( num ) { counter += num return counter } } const addValue1 = add (); console . log ( addValue1 ( 2 )) console . log ( addValue1 ( 4 )) console . log ( addValue1 ( 1 )) console . log ( addValue1 ( 9 )) console . log ( addValue1 ( 1 )) const addValue2 = add (); console . log ( addValue2 ( 10 )) console . log ( addValue2 ( 20 ))

A component is changing an uncontrolled input of type text to be controlled error in ReactJS - Formik

 https://stackoverflow.com/questions/47012169/a-component-is-changing-an-uncontrolled-input-of-type-text-to-be-controlled-erro default value can't be undefined  case 'listingBrokerOfficeName' : value = ( listingBroker || {}). officeName break change to: case 'listingBrokerOfficeName' : value = ( listingBroker || {}). officeName || '' break

pub/sub trigger by Cloud Scheduler - cloud function - firebase emulator for pub/sub

The problem: sending notifications to the owner of the expired listing The solution: target pub/sub - publish messages with Cloud scheduler on 11 pm daily create topic/subscription - "cron-topic" / " sub_push_cron " delivery type: push ( pull ) setup endpoint on backend NodeJS use NGROK to make the local NODE server available for Google Pub/Sub https://3274d032fcc7.ngrok.io/copper?token=YOUR_TOKEN_00hfMQOXpD axios Graphql API: processExpiredListins (getExpiredListins => owners => sendNotificaton) The Benefit: why no cloud function needed?  https://cloud.google.com/scheduler/docs/tut-pub-sub Firebase Emulator

merge strategy -

 

google pub/sub

setup local: start ngrok   ./ngrok http 3000 change env-dev.env PUBSUB_PUSH_ENDPOINT=https://299836d986cf.ngrok.io/copper start emulator firebase emulators:start create topic mutation { createPubSubTopic ( topicName : "copper" ) create subscription mutation { createPubSubPushSubscription ( topicName : "copper" subscriptionName : "sub_push_copper" ) } run mutation:  mutation { changeListingStatus ( input : { listingId : "hnWkg6i3vVtyohzVncpfr7" listingStatus : "SOLD" closingDate : "12/12/2020" soldPrice : "300000" buyerName : "John doe" agentName : "John A" agentOffice : "Agent Corp" titleCompany : "Title Corp" escrowCompany : "E Corp" } ) { success } }

Outdoor Tile Expansion Joints for tiles and concrete slab - tiles on concrete slab - how to grout outdoor tiles

If there are joints in the concrete slab under the tile, there needs to be an expansion joint in the concrete slab, as well. What Expansion Joints Are and Why You Should Use Them Expansion joints are spaces between tiles that, instead of being filled with  grout , are filled with a flexible sealant. The type of sealant (also called the "caulk" or "caulking") chosen must be weather-resistant. Moreover, if you expect to be subjecting your patio to a lot of traffic, you must select a sealant designed to hold up to foot traffic. Note that even indoor tiling projects require the use of these joints. The elements can take their toll on pieces of tile used outdoors. These elements include direct sunlight, freezing temperatures, and snow and rain. All of these conditions can cause outdoor tile to move, and you need to allow room for it to do so. If the outdoor tile does not have room to move, it will  make  room. Grout will crack. Outdoor tiles will pop themselves ...

What is a “closure” in JavaScript?

What is a “closure” in JavaScript? A closure is a function having access to the parent scope, even after the parent function has closed. const add = (()=> {   var counter = 0;   return function () {     counter += 1;     return counter;   }; })(); console.log(add())  //1 console.log(add())  //2 Describe event driven and asynchronous programming, and why it is important in User Interface Javascript? event-driven programming is a programming paradigm in which the flow of the program is determined by events such as user actions (mouse clicks, key presses), sensor outputs, or messages from other programs or threads., handling of events can either be synchronous or asynchronous.  Asynchronous programming in JavaScript offers a great way of handling operations (I/O) that are not immediately executed and therefore have no immediate response. Rather than waiting for long-running operations to return, blocking the execution thread in the proce...