React-select auto loading options - reactjs

This if my first question on SO so hopefully I dont forget anything.
I am currently developing a site with React that allows the customer to type in the first few letters of a vehicle name and it searches the database bringing back results. I am also accessing this site directly from another site via react-router and an iframe.
When I am coming in from the external site, I will be passing a query to react-router. The query will come in something like:
http://localhost:9292/#/?id=362789&start=1446015600000&stop=1446101999999
I would like react-select to automatically getOptions if "id" was included in the query. Otherwise I would like it to continue to wait for user input as it is working now.
My current code looks something like. I know I will need a if/else statement but more concerned with the auto-loading factor for now:
render() {
const asset_id = this.props.id
const getOptions = (input) => {
return fetch(`/subject?q=${input}`, {credentials: 'include'})
.then((response) => {
return response.json();
}).then((data) => {return {options: data}});
}
return (
<div className="picker">
<Select.Async
loadOptions={getOptions}
minimumInput={2}
value={this.state.selectValue}
onChange={this.updateValue.bind(this)}
ref="dropdown"
name="chooser"
/>
</div>
}
Any help you could give would be wonderful. Im still getting familiar with React and I feel I am overlooking something simple possibly.

Related

Using keys with graphql fragment masking

As far as I know, fragment masking is considered a best practice when developing graphql clients, but I'm having some difficulties wrapping my head around how to write even some simple react necessities with that level of obscurity. One common necessity is providing key properties in iterations:
One example I'm working on is pulling repository data from Github to print cards with each of them. The query is:
fragment RepositoryCard on Repository {
resourcePath
description
}
Then, I'd use this query in a bigger one that request a user profile and gets some of their repositories:
query GetUserData($login: String!) {
user(login: $login) {
bio
name
repositories(first: 10) {
edges {
node {
...RepositoryCard
}
}
}
}
}
So far, so good. Then I'd map the responses to cards:
{
data?.user?.repositories?.edges?.map((repository) => (
<RepositoryCard
className="my-2"
repositoryNode={repository?.node}
/>
))
}
But then, I need a key prop for this iteration. The best approach would be to use the resourcePath since that's unique. However, since fragment masking is used, graphql-codegen doesn't allow me to see the contents of the type of repository.node, so I can't access resourcePath from outside of the component to get it.
What's the common approach to solve this?
It seems like useFragment is not a real hook, so it isn't necessary to follow the rules of hooks. In an answer to another question I see that the solution is to simply rename that function to something that won't trigger warnings (and better show the fact that it isn't a hook), so in your codegen.ts:
generates: {
"./src/__generated__/": {
preset: "client",
plugins: [],
presetConfig: {
gqlTagName: "gql",
fragmentMasking: {
unmaskFunctionName: "getFragmentData",
}
}
}
Then you can just call getFragmentData (previously useFragment) inside the map without getting any warnings:
data?.repositories?.edges?.filter((r) => !!(r?.node))
.map((r) => r?.node)
.map((repository) => {
const key = getFragmentData(REPOSITORY_CARD_FRAGMENT, repository)!.resourcePath;
return (
<RepositoryCard
key={key}
className="my-2"
query={repository!}
/>
);
})

Algolia: Export React Instant Search results

Is there any way to export Algolia's React Instant Search results to a CSV? I've tried using the react-csv package, but it doesn't work with Algolia's Hit Component. The package requires data as props, but the data is constantly changing since it's React Instant Search.
What I mean by constantly changing is that on page load, you're given the entire index of records found, then you can narrow down the results with the search bar or other filtering components.
I've gone down the Google rabbit hole looking for information about exporting Algolia's search results as a CSV, but I haven't found anything regarding React Instant Search—unless I completely missed it.
Has anyone tried this before? If so, could you point me in the right direction regarding documentation or examples?
Not sure if this solves your problem but one possible way is to use the StateResults widget. The StateResults widget provides a way to access the searchState and the searchResults of InstantSearch.
Here I will create a custom StateResults component in the form of a download button and then connect it using the connectStateResults connector.
I have attached a demo below as well.
For simplicity I didn't format the data to be fed into the CSV builder.
// 1. Create a React component
const StateResults = () => {
// return the DOM output
};
// 2. Connect the component using the connector
const CustomStateResults = connectStateResults(StateResults);
// 3. Use your connected widget
<CustomStateResults />
In your case something like
const StateResults = ({ searchResults }) => {
const hits = searchResults?.hits;
return (
<div>
<button>{hits && <CSVLink data={hits}>Download CSV</CSVLink>}</button>
</div>
);
};
const DownloadButton = connectStateResults(StateResults);
//in your JSX then <DownloadButton />

How to mange a paste event within CKEdit 5 React component?

When you employ the CKEditor, the user might try to be edgy and paste several thousand lines at once. The browser wouldn't like that. One strategy would be to intercept the paste event and trim the data to a more manageable chunk.
Looking around I found this question - this is basically the same situation, I only can't get my head around how to achieve the same with the React component.
I'd also appreciate different and more insightful strategies.
In short, I posed a question directly in the developer's github issue tracker. With a lot of trail and error in the Javascript console and their eventual answer I managed to control the text coming in the CKEditor with a paste event.
Key points:
I used onInit prop. onReady didn't work for me.
The data in the paste event is divided in elements (like html ones) and is being accessed a bit weirdly.
I guess the best way to explain what I did would be to just show the code, so:
<CKEditor
id={id}
editor={ClassicEditor}
data={value}
onInit={editor => {
const documentView = editor.editing.view.document
documentView.on('paste', (event, data) => {
editor.plugins.get('Clipboard').on('inputTransformation', (event, data) => {
let accumulated = editor.getData()
for (const element of data.content.getChildren()) {
if (element._textData !== undefined) {
accumulated += element._textData
} else {
accumulated += element.getChild(0)._textData
}
if (accumulated.length >= SOME_LENGTH) {
event.stop()
editor.setData('')
editor.setData(accumulated.slice(0, SOME_LENGTH))
break
}
}
})
})
}}
onChange={(event, editor) => {
const data = editor.getData()
inputOnChange(data)
}}
/>
So that's it. I hope this shortens someone else's struggle a bit.

ReactJs : How to print data from console to web-page?

After a successful POST and GET query, the results of my operation are visible in the console of my React Dev Tools. How should I take those results, preferable create a table and render that table on my web-app itself?
Here is the GET request :
axios.get('http://localhost:5000/result')
.then((response) => {
console.log(response);
});
}
The format of results displayed on console is like this :
Let's say I want to create a table by traversing through the results with headers _id and Name. I know I should use the map function. But exactly where and how should I do that in my code?
You have a few options. You can make your call in componentDidMount, set the result in a state and then render that state.
componentDidMount() {
axios.get('http://localhost:5000/result')
.then((response) => {
this.setState({
data: response // maninpulate your response here
})
});
}
}
render() {
const { data } = this.state;
return this.renderTable(data) // this should return a table
}
Assuming you know the concept of 'useState' in react hooks. If not please have an understanding of it.
Long story short, useState is used to store the data in variables.
const [data, setData] = useState();
Instead of console.log(response); you set the response to the variable i.e; setData(response);
In html,
<table>
//some headers, if needed
//This will iterate your array of objects
{data.map((eachData) => (
<tr> <td>{eachData.id}</td>
<td>{eachData.name}</td>
....
</tr>
)
</table>
Please Note: The HTML part works for both class-based and function-based React components where as 'useState' is part of React hooks functionality, works only for function-based components.
I have created a small sample app where I have used react-table for displaying the data as a table. Also In this example I have added promise in order to simulate server fetching data from server. This you can replace with actual server call i.e., axis.get etc.
React-table provides a lot many features that might be helpful. Such as you can provide which columns you wish to display out of all the columns from the data.
If you do not wish to use any library for displaying table, that is also possible only that you have to replace ReactTable with your custom table implementation.
Hope this helps.
Thanks to this page: https://www.skptricks.com/2019/02/can-you-consolelog-in-jsx.html.
You can do console.log in the render function of a class component or in the return statement of a function component. In your case:
function Foo(props){
data = axios.get('http://localhost:5000/result')
return(
<>
{console.log(data)}
</>)
}
In my opinion, it's much more straight forward than the other state methods.

querying stripe api & display image

I have been following a tutorial to query Stripe API and display data. One thing that is not mentioned is how to query the images and display it. I can see from the structure that the images property is there but I need some help to display it. I assume it should be the same logic how it is displaying the product name but I just need to understand to follow the same logic for the images.
Here is my query, I have added the image option in my query:
and can see the result in GrapiQL:
Here is example of how I am mapping over my products to display correctly. From what I understand I need to do the same for the image. I have followed the same logic by just replacing product with image but just can't seem to get it working. Here is the snippet:
const Products = () => {
return (<StaticQuery query={PRODUCTS_QUERY}
render={
({ allStripeSku, allStripeProduct }) => {
return allStripeProduct.edges.map(product => {
const skus = allStripeSku.edges.filter(
sku => sku.node.product.id === product.node.id
)
return (
<Product
key={product.node.id}
skus={skus}
product={product.node} />
)
})
return
}
}
/>)
}
Can anyone please point my in the right direction so I can get this working?
You need to add 2 lines of code:
in GraphQL query to return images alongside id and name as you've already done
in ProductCard component to return an <img> element using the query field added above
For me this meant adding the + lines below:
in src/components/Products/Products.js
in src/components/Products/ProductCard.js
I assume it's the Gatsby E-commerce Tutorial you were following; if so please be aware that, since your OP, they've updated the docs so it no longer uses the deprecated Orders API.

Resources