react native parsing Lottie file into state? - animation

I am trying to implement Lottie animation into my app, i am using expo SDK,
so i followed the documentation on expo,
_loadAnimationAsync = async () => {
let result = await fetch(
'https://cdn.rawgit.com/airbnb/lottie-react-native/635163550b9689529bfffb77e489e4174516f1c0/example/animations/Watermelon.json'
);
this.setState(
{ animation: JSON.parse(result._bodyText) },
this._playAnimation
);
};
i got an [Unhandled promise rejection: SyntaxError: JSON Parse error: Unexpected identifier "undefined"].
is it result ._bodyText who is empty or undefined ??

I just meet the same issue and fixed.
modify _loadAnimationAsync should get it work.
_loadAnimationAsync = async () => {
let result = await fetch(
'https://cdn.rawgit.com/airbnb/lottie-react-native/635163550b9689529bfffb77e489e4174516f1c0/example/animations/Watermelon.json'
)
.then(data => {
return data.json();
})
.catch(error => {
console.error(error);
});
this.setState({ animation: result }, this._playAnimation);
};
I also start a pr for this issue if you are interested. here

Related

Debounce in redux-tool-kit

I'm Trying to debounce below API call with using lodash debounce
export const getProfile = createAsyncThunk(
GET_PROFILE,
async (amount: any, { rejectWithValue }: any) => {
try {
const response = await API.Get(EndPoint.GET_PROFILE)
console.log(response)
return response.data
} catch (error: any) {
amount.failCallBack(error?.response?.data?.msg || 'something_went_wrong')
return rejectWithValue(error?.code || 'Something went wrong..!')
}
}
)
above function is worked without any errors and fetch data able to see inside fullfilled of the action
so i tried to implement debounce as below way
export const getProfile = createAsyncThunk(
GET_PROFILE,
debounce(async (amount: any, { rejectWithValue }: any) => {
try {
const response = await API.Get(EndPoint.GET_PROFILE)
console.log(response)
return response.data
} catch (error: any) {
amount.failCallBack(error?.response?.data?.msg || 'something_went_wrong')
return rejectWithValue(error?.code || 'Something went wrong..!')
}
}, 5000)
)
Now there is no any exceptions in web app and when i console log the fullfilled action it shows
payload as undefined
{
"type": "login/getProfile/fulfilled",
"meta": {
"arg": {
"data": "login"
},
payload: undefined,
"requestId": "8pfalpIzFl8nNOgi2jRcb",
"requestStatus": "fulfilled"
}
}
any suggestions for fix this issue.
thanks in advance
Don't debounce the payload creator - debounce dispatching the thunk action. And since you probably don't want to that in your component, do it in a manual thunk
const getProfile = createAsyncThunk( ... normal definition ... );
const debounced = debounce((arg, dispatch) => dispatch(getProfile(arg)), 5000);
const debouncedGetProfile = (arg) => (dispatch) => debounced(arg, dispatch)
and then use that
dispatch(debouncedGetProfile(amount))

Cypress adding context to failed tests

I would like to add some context on each fail by getting some localstorage data and log that.. but not really sure how I can do it
In index.ts I added
Cypress.on('fail', (error, runnable) => {})
and there I do const user = localStorage.getItem('user'); and try to log it but now luck.. guess that I need to fetch it async but not able to get it to work :/
Use the synchronous version of .log().
I guess the queue stops running before the fail event is captured.
Cypress.on('fail', (error, runnable) => {
const user = localStorage.getItem('user')
Cypress.log({name: 'User', message: user})
})
it('', () => {
localStorage.setItem('user', 'my-user')
expect(1).to.eq(2)
})
I actually got it working by doing this in my support/index.ts file...
Cypress.on('fail', (error) => {
const asyncLocalStorage = {
getItem(key) {
return Promise.resolve().then(function () {
return localStorage.getItem(key);
});
},
};
asyncLocalStorage.getItem('state').then((localStorageState) => {
const state = JSON.parse(localStorageState);
Cypress.log({
name: error.name,
message: error.message,
consoleProps: () => ({
'User Id': state?.user?.id,
members: state?.members,
message: error.message,
stack: error.stack,
}),
});
});
throw error;
});

Async await not working for function - create pdf document and then email it

const pdf = require('pdfkit')
const QR = require('qrcode')
const emailTickets = async (userEvent, tickets) => {
await createQRCodes(tickets)
await createTicketPDF(tickets, userEvent)
await sendGridEmail(emailDetails, true)
}
The problem seems to be that async/await isn't working properly for the createTicketPDF function.
When I run the above emailTickets function a blank pdf document is emailed. However, when I run it with the below setTimeOut, the pdf contains all the detail that I want.
const emailTickets = async (userEvent, tickets) => {
await createQRCodes(tickets)
await createTicketPDF(tickets, userEvent)
setTimeout(async() => {await sendGridEmail(emailDetails, true)}, 5000);
}
I would prefer a solution where the code waited for the createTicketPDF function to finish before calling the sendGridEmail function.
Below is the code for the createTicketPDF function:
const createTicketPDF = async (tickets, userEvent) => {
const doc = new pdf
doc.pipe(fs.createWriteStream(`./tickets/${tickets[0]._id}.pdf`))
await tickets.map(async(ticket, index)=> {
return(
await doc.fontSize(30),
await doc.text(userEvent.title),
await doc.fontSize(10),
await doc.moveDown(),
await doc.text(`Venue: ${userEvent.venue}, ${userEvent.address1} `),
await doc.moveDown(),
await doc.fontSize(20),
await doc.text(`Ticket ${index+1} of ${tickets.length}: ${ticket.ticketType}`),
await doc.image(`./qrCodes/${ticket._id}.png`, {
align: 'center',
valign: 'center'
}),
await doc.addPage()
)
})
doc.end()
}
I had a forEach loop in this function but replaced it with a map on learning that forEach loops don't work well with async await.
I have also tried using (const ticket of tickets){} but this didn't work either
VS code is suggesting that none of the awaits within the map do anything
For completeness, below is the createQRCodes. This function is working perfectly.
const createQRCodes = async (tickets) => {
let CreateQRCodes = tickets.map(ticket => {
return(
QR.toFile(`./qrCodes/${ticket._id}.png`, String([ticket._id, ticket.randomNumber, ticket.creationTime.getTime(), ticket.userEvent]))
)})
await Promise.all(CreateQRCodes)
}
Any ideas where I am going wrong
Twilio SendGrid developer evangelist here.
As far as I can tell from the documentation, PDFKit is a synchronous library. The only thing that is asynchronous is writing the PDF to disk. So your code should not need to await anything within the createTicketPDF function. You do need to listen for the stream to finish though, so you could return a promise that resolves when the stream is finished, like this:
const createTicketPDF = (tickets, userEvent) => {
const doc = new pdf
const stream = doc.pipe(fs.createWriteStream(`./tickets/${tickets[0]._id}.pdf`))
tickets.map((ticket, index)=> {
return(
doc.fontSize(30),
doc.text(userEvent.title),
doc.fontSize(10),
doc.moveDown(),
doc.text(`Venue: ${userEvent.venue}, ${userEvent.address1} `),
doc.moveDown(),
doc.fontSize(20),
doc.text(`Ticket ${index+1} of ${tickets.length}: ${ticket.ticketType}`),
doc.image(`./qrCodes/${ticket._id}.png`, {
align: 'center',
valign: 'center'
}),
doc.addPage()
)
})
doc.end()
const promise = new Promise((resolve) => {
stream.on("finish", () => {
resolve();
})
});
return promise;
}
const emailTickets = async (userEvent, tickets) => {
await createQRCodes(tickets)
await createTicketPDF(tickets, userEvent)
await sendGridEmail(emailDetails, true)
}

TypeError: Cannot read property 'type' of undefined (redux toolkit)

I'm trying to fetch some data with redux toolkit but it doesn't work. I just keep getting the error TypeError: Cannot read property 'type' of undefined. I set up the store correct because i have other reducer working fine. But when i tried the asyn or fetch data, i have this problem
Error:
App.js:
The code stop at const actionResult = await dispath(getLiveContest()) it doesn't console log anything after.
const dispatch = useDispatch();
useEffect(() => {
const fetchLiveContest = async () => {
try {
console.log(1);
const actionResult = await dispatch(getLiveContest());
console.log(2);
const liveContest = unwrapResult(actionResult);
console.log(liveContest);
} catch (error) {
console.log("Failed to fetch live contest: ", error);
}
};
fetchLiveContest();
}, []);
GetLiveContest():
Here is the code of the function. I tried to return {name: 'lala'} and it's still gave me the type error
export const getLiveContest = createAsyncThunk(
"contests/fetchLive",
async (params, thunkAPI) => {
console.log(thunkAPI, "thunkAPI");
console.log(params);
const liveContest = await axios ...
return liveContest;
}
);
Code of the slide:
export const liveContestSlide = createSlice({
name: "live",
initialState: {
contest: [],
loading: "idle",
},
reducers: {},
extraReducers: {
// Add reducers for additional action types here, and handle loading state as needed
[getLiveContest.fulfilled]: (state, action) => {
// Add contest to the state array
state.contest.push(action.payload);
},
},
});
I followed the redux toolkit doc. I also checkout other question on stackoverflow but still can't fix the error, pls help
I just change import getLiveContest from "./contestSlice"; to import { getLiveContest } from "./contestSlice"; and it work, turn out i just import the function wrong

Webdriverio wait until visible

I'm using webdriverio and need to wait for an element to be in the viewport
So I tried
browser.waitUntil(async () => {
const b = await link.isDisplayedInViewport()
return b;
}, 5000, 'expected to be visible after 5s');
But somehow waitUntil wants a boolean not a Promise<boolean>
How can I fix this?
Update:
I use WebdriverIO in a NodeJs app as follows
const { remote } = require('webdriverio');
(async () => {
const browser = await remote({
logLevel: 'error',
path: '/',
capabilities: {
browserName: 'chrome'
}
});
await browser.url('https://example.com');
const link = await browser.$('.special-link');
const ok = await browser.waitUntil(async () => {
const b = await link.isDisplayedInViewport()
return b;
}, 5000, 'expected to be visible after 5s');
await link.click();
const title = await browser.getTitle();
console.log('Title was: ' + title);
await browser.deleteSession();
})().catch((e) => console.error(e));
source
In the options is don't see anything about with or without async/await. Furthermore I don't use a testing framework!
Sorry for the late answer. But if you are still looking for a solution, Please try this if you want to avoid aync/await
get link() { return browser.element('.special-link'); }
browser.waitUntil(() => this.link.isVisibleWithinViewport(), 20000, 'link not visible')
const elementWaitingToBeDisplayed = $("some element locators")
elementWaitingToBeDisplayed.waitForDisplayed(10000, false)
If you set the second argument of elementWaitingToBeDisplayed.waitForDisplayed to true it waits for the opposite.

Resources