I am using the default formatting settings for React Native project. Prettier ("#react-native-community/eslint-config": "^2.0.0",). My if statements do not look good at least to me. I like to know if my if statements should be formatted as shown below or differently. Below is how prettier is formatting. Is there a better method. If so please post detailed information
const connect = async (addresses, port) => {
// check purchase information (entitlement)
try {
const purchaserInfo = await Purchases.getPurchaserInfo();
if (
typeof purchaserInfo.entitlements.active[DEFAULT_ENTITLEMENT_ID] !==
"undefined"
) {
// Grant user "pro" access
setNetwork(`http://${addresses[0]}:${port}`);
}
} catch (e) {
// Error fetching purchaser info
Bugfender.d('Purchases Error', e.message ); //prettier-ignore
}
};
It seems that your if condition is lengthy.
By default, Prettier’s printing algorithm prints expressions on a single line if they fit. It really helps readability if long single line converted to multi line. That's why long single line are automatically expanded.
Click here to read more
Related
Background
I have recently upgraded a fairly sizeable React app to React 18 and for the most part it has been great. One of the key changes is the new double mount in development causing useEffect hooks to all run twice, this is clearly documented in their docs.
I have read their new effect documentation https://beta.reactjs.org/learn/lifecycle-of-reactive-effects and although it is quite detailed there is a use case I believe I have found which is not very well covered.
The issue
Essentially the issue I have run into is I am implementing OAuth integration with a third-party product. The flow:
-> User clicks create integration -> Redirect to product login -> Gets redirected back to our app with authorisation code -> We hit our API to finalise the integration (HTTP POST request)
The problem comes now that the useEffect hook runs twice it means that we would hit this last POST request twice, first one would succeed and the second would fail because the integration is already setup.
This is not potentially a major issue but the user would see an error message even though the request worked and just feels like a bad pattern.
Considered solutions
Refactoring to use a button
I could potentially get the user to click a button on the redirect URL after they have logged into the third-party product. This would work and seems to be what the React guides recommend (Although different use case they suggested - https://beta.reactjs.org/learn/you-might-not-need-an-effect#sharing-logic-between-event-handlers).
The problem with this is that the user has already clicked a button to create the integration so it feels like a worse user experience.
Ignore the duplicate API call
This issue is only a problem in development however it is still a bit annoying and feels like an issue I want to explore further
Code setup
I have simplified the code for this example but hopefully this gives a rough idea of how the intended code is meant to function.
const IntegrationRedirect: React.FC = () => {
const navigate = useNavigate();
const organisationIntegrationsService = useOrganisationIntegrationsService();
// Make call on the mount of this component
useEffect(() => {
// Call the method
handleCreateIntegration();
}, []);
const handleCreateIntegration = async (): Promise<void> => {
// Setup request
const request: ICreateIntegration = {
authorisationCode: ''
};
try {
// Make service call
const setupIntegrationResponse = await organisationIntegrationsService.createIntegration(request);
// Handle error
if (setupIntegrationResponse.data.errors) {
throw 'Failed to setup integrations';
}
// Navigate away on success
routes.organisation.integrations.navigate(navigate);
}
catch (error) {
// Handle error
}
};
return ();
};
What I am after
I am after suggestions based on the React 18 changes that would handle this situation, I feel that although this is a little specific/niche it is still a viable use case. It would be good to have a clean way to handle this as OAuth integration is quite a common flow for integration between products.
You can use the useRef() together with useEffect() for a workaround
const effectRan = useRef(false)
useEffect(() => {
if (effectRan.current === false) {
// do the async data fetch here
handleCreateIntegration();
}
//cleanup function
return () => {
effectRan.current = true // this will be set to true on the initial unmount
}
}, []);
This is a workaround suggested by Dave Gray on his youtube channel https://www.youtube.com/watch?v=81faZzp18NM
I've been working on creating discord bots using discord.js, and they've gotten large enough that I'd like to be able to set up automated testing for them - I've found this library (corde), but as it doesn't seem to be widely used, I'd like to see if there are other, more mature options available out there first.
Any help would be greatly appreciated. Manually testing bot commands one at a time is growing somewhat tiring.
If you read some of the examples in the github repo, you can simply set the prefix of all of your bots as the same (or change the code below) and then as the client logs in, it tests a command.
const { group, test, command, beforeStart, afterAll } = require("corde");
const { client, loginBot } = require("..");
beforeStart(() => {
loginBot();
});
group("main commands", () => {
test("Hello command should return... hello!!", () => {
expect("ping").shouldReturn("Ping?");
});
});
afterAll(() => {
client.destroy();
});
There is far more code that will help in the repo, here is the main index.js file if you need more assistance, or you could ask in a comment below.
I am trying to save a variable's data into a text file and update the file every time the variable changes. I found solutions in Node.js and vanilla JavaScript but I cannot find a particular solution in React.js.
Actually I am trying to store Facebook Long Live Access Token in to a text file and would like to use it in the future and when I try importing 'fs' and implementing createFile and appendFile methods I get an error saying Method doesn't exist.
Please help me out. Here is the code below
window.FB.getLoginStatus((resp) => {
if (resp.status === 'connected') {
const accessToken = resp.authResponse.accessToken;
try {
axios.get(`https://graph.facebook.com/oauth/access_token?client_id=CLIENT_id&client_secret=CLIENT_SECRET&grant_type=fb_exchange_token&fb_exchange_token=${accessToken}`)
.then((response) => {
console.log("Long Live Access Token " + response.data.access_token + " expires in " + response.data.expires_in);
let longLiveAccessToken = response.data.access_token;
let expiresIn = response.data.expires_in;
})
.catch((error) => {
console.log(error);
});
}
catch (e) {
console.log(e.description);
}
}
});
React is a frontend library. It's supposed to be executed in the browser, which for security reasons does not have access to the file system. You can make React render in the server, but the example code you're showing is clearly frontend code, it uses the window object. It doesn't even include anything React-related at first sight: it mainly consists of an Ajax call to Facebook made via Axios library.
So your remaining options are basically these:
Create a text file and let the user download it.
Save the file content in local storage for later access from the same browser.
Save the contents in online storage (which could also be localhost).
Can you precise if any of these methods would fit your needs, so I can explain it further with sample code if needed?
I am working through Angular Meteor tutorial and got deprecation warning on
this.helpers({
parties: () => {
return Parties.find({}); //deprecation warning. Use getReactively
}
});
But I am not quite sure how to get all records reactively. I do not have any queries to say return Parties.find({field: this.getReactively(query)}). I just want all records/everything similar to Collection.find({}) or Parties.find({}) but without deprecation warning.
Im often use parties: ()=> Parties.find() and I'm has no error or deprecated warning. You maybe should try it.
Beside, sometime I need handle data fetch from query. Im used a temp variable for save data before handle it.
You can try (some code is pseudo code)
parties: () {
this.temp = Parties.find().fetch();
if(this.temp) {
//handle data, adjust property like format string, format date....
return this.temp
}
}
Its work, no deprecated, no error. You can try it.
While rendering React components on server all of the propTypes warning messages are falling to general output or process.stdout. For example, this is visible only in terminal or in general application log:
Warning: Failed propType: Required prop `title` was not specified in `Page`.
Is there any way to catch this warnings and transform them or pipe them into another direction? For instance, I want to separate application log and React (as template engine) log. How can I do it?
Like #m01, I wanted to make sure that any react errors (and in fact any js errors) cause my unit tests to fail, but I found a much simpler way to do it. At the top level of your tests, put this:
beforeAll(() => {
console.error = (error) => {
throw new Error(error);
};
});
I needed the same thing, but for a different use case. I wanted to make sure that all my unit tests pass without any React warnings.
I use this in my test utils:
expectNoConsoleErrors: function() {
var savedErrors;
beforeEach(function () {
savedErrors = [];
spyOn(console, 'error').and.callFake(function () {
var stack = new Error(_.map(arguments).join(' ')).stack;
// if you need workarounds for come components, put them here
savedErrors.push(stack);
});
});
afterEach(function () {
if (savedErrors.length > 0) {
fail(savedErrors.join('\n'));
}
});
},
Then in describe block I put
myTestUtils.expectNoConsoleErrors()
And it works like a charm.
This is not very clean because it will also catch all other calls to console.error, but I don't want them during test anyway, so this seems ok for me.
Also, when I have some misbehaving component producing unnecessary warnings, like e.g. react-input-autosize I can ignore it using:
// Workaround for https://github.com/JedWatson/react-select/issues/371
if (_.contains(stack, 'react-input-autosize')) {
return;
}
Btw, note that before v0.14, React was using console.warn instead of console.error to produce these warnings.
I tried looking into the React src how they print those output messages, but then I realized that it should only be printing those messages in development mode. If your node/iojs runtime is set to the "production" env, React should not even be doing those checks and that's what you want for a real app running. Those warnings are meant just for devs running locally.