-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: refactor useMarketoForm to use a state machine
- Loading branch information
1 parent
5be934e
commit 578659d
Showing
2 changed files
with
81 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,88 @@ | ||
import { useEffect, useState } from 'react'; | ||
import { navigate } from 'gatsby'; | ||
import { assign, Machine } from 'xstate'; | ||
import { asEffect, useMachine } from '@xstate/react'; | ||
import useScript from './useScript'; | ||
|
||
const useMarketoForm = (munchkinId, id, publishableKey, redirectLink) => { | ||
const [loaded, setLoaded] = useState(false); | ||
|
||
useEffect(() => { | ||
if (!window.MktoForms2) { | ||
return; | ||
} | ||
setLoaded(true); | ||
const machine = Machine({ | ||
id: 'marketo', | ||
initial: 'loading', | ||
context: { | ||
form: null, | ||
error: null, | ||
}, | ||
states: { | ||
loading: { | ||
on: { LOADED: 'scriptLoaded', LOAD_ERROR: 'error', BLOCKED: 'blocked' }, | ||
}, | ||
scriptLoaded: { | ||
entry: ['loadForm'], | ||
on: { | ||
FORM_LOADED: { | ||
target: 'formLoaded', | ||
actions: assign({ form: (_context, event) => event.form }), | ||
}, | ||
BLOCKED: 'blocked', | ||
}, | ||
}, | ||
formLoaded: { | ||
type: 'final', | ||
entry: ['defineFormActions'], | ||
}, | ||
blocked: { | ||
type: 'final', | ||
entry: assign({ | ||
error: | ||
'Unable to load the script. Perhaps this was due to an ad blocker.', | ||
}), | ||
}, | ||
error: { | ||
type: 'final', | ||
entry: assign({ error: 'Unable to load the script.' }), | ||
}, | ||
}, | ||
}); | ||
|
||
window.MktoForms2.loadForm( | ||
'//app-abj.marketo.com', | ||
munchkinId, | ||
id, | ||
(form) => { | ||
// eslint-disable-next-line no-unused-vars | ||
form.onSuccess(function (values, followUpUrl) { | ||
const useMarketoForm = (munchkinId, id, publishableKey, redirectLink) => { | ||
const [state, send] = useMachine(machine, { | ||
actions: { | ||
loadForm: asEffect(() => { | ||
window.MktoForms2.loadForm( | ||
'//app-abj.marketo.com', | ||
munchkinId, | ||
id, | ||
(form) => send({ type: 'FORM_LOADED', form }) | ||
); | ||
}), | ||
defineFormActions: asEffect(({ form }) => { | ||
form.onSuccess(() => { | ||
navigate(redirectLink); | ||
|
||
// prevent the default behavior of redirecting via marketo to another | ||
// page. We want to control the navigation ourselves. | ||
// https://developers.marketo.com/javascript-api/forms/api-reference/ | ||
return false; | ||
}); | ||
} | ||
); | ||
}), | ||
}, | ||
}); | ||
|
||
const pollForDefinition = (scope, varname, callback) => { | ||
if (typeof scope[varname] !== 'undefined') { | ||
return callback(); | ||
useScript('https://marketo.clearbit.com/assets/v1/marketo/forms.js', { | ||
attributes: { 'data-clearbit-publishable-key': publishableKey }, | ||
onError: () => send('LOAD_ERROR'), | ||
onLoad: () => { | ||
if (window.MktoForms2) { | ||
send('LOADED'); | ||
} else { | ||
// Some ad blockers block the marketo script from loading. In this case, | ||
// we won't have the MktoForms2 variable available on window. We need | ||
// to prevent the rest of the script from running to avoid triggering | ||
// errors on the page that would cause the page to go blank. | ||
send('BLOCKED'); | ||
} | ||
const interval = setInterval(() => { | ||
if (typeof scope[varname] !== 'undefined') { | ||
clearInterval(interval); | ||
callback(); | ||
} | ||
}, 250); | ||
}; | ||
const script = document.createElement('script'); | ||
script.src = 'https://marketo.clearbit.com/assets/v1/marketo/forms.js'; | ||
script.async = true; | ||
script.setAttribute('data-clearbit-publishable-key', publishableKey); | ||
script.onerror = () => { | ||
// eslint-disable-next-line no-console | ||
console.log('Clearbit Form JS unable to load'); | ||
pollForDefinition(window, 'MktoForms2', () => { | ||
window.MktoForms2.whenReady((form) => { | ||
form.setValues({ | ||
clearbitFormStatus: 'Clearbit Form JS unable to load', | ||
}); | ||
}); | ||
}); | ||
}; | ||
document.body.append(script); | ||
}, [munchkinId, id, publishableKey, redirectLink]); | ||
}, | ||
}); | ||
|
||
return loaded; | ||
return [state.value, state.context]; | ||
}; | ||
|
||
export default useMarketoForm; |