Prifina Components
What are Prifina components?
Like other hooks Prifina’s own hooks allow you to use many of the Prifina features and states.
The main focus is on the
usePrifina
hook that offers extracted logic to help you connect your custom widget or app to the Prifina platform and make it alive.It’s always good to use the ‘latest’ for version number to stay in touch with latest releases.
"@prifina/hooks": "latest"
Manual installation
yarn add @prifina/hooks # yarn
You can find out more about
usePrifina
hook in the toggle below.usePrifina
The usePrifina hook allows the use of Prifina’s custom context value.
Creates custom context object using prifinaContext. After it returns current memoized value of the prifinaContext object with the help of React’s useMemo.
Memoized means that the cached value of a complex function is called. If the arguments of the function that is called are the same, computing of the function will not be needed again, it simply uses the stored value.
export const usePrifina = () => { const prifinaContext = useContext(PrifinaContext); const prifina = useMemo(() => { return prifinaContext.current; }, [prifinaContext]); return prifina; };
Importing
import { usePrifina } from "@prifina/hooks";
Usage
Let’s see how it looks in practice.
Set yout
appID
which must be 10 characters long - you can claim it once you sign up as developer in App Studio or get in touch on Slackconst appID = "0123456789"; // id should be random 10 character string
Assign variables:
onUpdate
, Prifina
, API
, and registerHooks
to usePrifina
hookconst { onUpdate, Prifina, API, registerHooks } = usePrifina();
onUpdate
, API
, and registerHooks
are used with useEffect
hookonUpdate
- callback function used for background updates and notifications inside Prifina platfrom
API
- used in await function to wait for a promise from data connectors custom query
registerHooks
- register data source modules
useEffect(async () => { // init callback function for background updates/notifications onUpdate(appID, dataUpdate); // register datasource modules registerHooks(appID, [DataConnector]); const result = await API[appID].DataConnector.customQueryFunction({}); }, []);
Let’s add
filter
so you can choose what data you want to receive rather than bother yourself with waiting for the whole data model to return - which can be a very long time.useEffect(async () => { onUpdate(appID, dataUpdate); registerHooks(appID, [DataConnector]); const d = new Date(); const dd = d.setDate(d.getDate() - 14); const dateStr = new Date(dd).toISOString().split("T")[0]; const filter = { ["s3::date"]: { [Op.gte]: dateStr, }, }; const result = await API[appID].DataConnector.customQueryFunction({ filter: filter, fields: "day_start,class_5min", }); }, []);
You can se constant
d
called as a constructor, returns a new Date
object.It’s implemented further in
dd
to get a date value of -14
which will get you a starting date from 14 days ago.
This is how you will get a period of recent 14 days of data - it will look something like this: 1640875396784
Now we use
dateStr
to convert that value to string, so the final product is 2021-12-30
.To be able to go to next step in filtering we’ll need to also enable data query Operator by importing it from
“@prifina/hooks”
import { usePrifina, Op } from "@prifina/hooks";
Once we do we implement it in
filter
with the help of SQL syntax expression, we get all the date values greater than or equal to ( gte
) from dateStr
starting point.const filter = { ["s3::date"]: { [Op.gte]: dateStr, }, };
In final step after we have filtered a period of data we need to process it - we’ll do that with the help of processData() function.
If there are multiple data connectors used or one data connector with different query functions just repeat the same process every time and place them inside separate
processData()
functions. You can use the sam useEffect
hook to pass the data to them.Final look:
const [finalData, setFinalData] = useState(""); const processData = (data) => { //receiving passed data const processedData = ... //processing the data further to get desired data object //useState hook can help with declaring the final product setFinalData(processedData); } useEffect(async () => { // init callback function for background updates/notifications onUpdate(appID, dataUpdate); // register datasource modules registerHooks(appID, [Oura]); const d = new Date(); const dd = d.setDate(d.getDate() - 14); const dateStr = new Date(dd).toISOString().split("T")[0]; console.log(dateStr, "sda"); const filter = { ["s3::date"]: { [Op.gte]: dateStr, }, }; const activityResult = await API[appID].Oura.queryActivitySummariesAsync({ filter: filter, fields: "day_start,class_5min", }); //adding processData function passing the activityResult object if (stage === "dev") { processData(activityResult.data.getDataObject.content[1]); } }, []);
dataUpdate
Async function used to update the widgets properties and enable control and interaction of the same - mainly used in widget settings. Declared using
onUpdate
in useEffect
hook alongside appID
let defaultCity = city; if ( typeof data !== "undefined" && data.hasOwnProperty("settings") && typeof data.settings === "object" && data.settings.hasOwnProperty("city") && data.settings.city.length > 0 ) { defaultCity = data.settings.city; } const [searchCity, setCity] = useState(defaultCity); const dataUpdate = async (payload) => { if ( payload.hasOwnProperty("settings") && typeof data.settings === "object" && payload.settings.hasOwnProperty("city") ) { setCity(payload.settings.city); setUrl( `${API_BASE_URL}/data/2.5/onecall?q=${data.settings.city}&units=metric&appid=${API_KEY}` ); } if ( payload.hasOwnProperty("data") && payload.data.hasOwnProperty("content") ) { // process async data if ( payload.data.dataconnector === "Oura/queryActivitySummariesAsync" && payload.data.content.length > 1 ) { processData(payload.data.content); } } };