Forum Discussion
spfx React > REST API > Map search results
- Oct 23, 2017
I had to create my own version of the web part to test the code. This works for me :-)
import * as React from 'react'; import styles from './HelloWorld.module.scss'; import { IHelloWorldProps } from './IHelloWorldProps'; import { escape } from '@microsoft/sp-lodash-subset'; import { SPHttpClient, SPHttpClientConfiguration, SPHttpClientResponse, ODataVersion, ISPHttpClientConfiguration } from '@microsoft/sp-http'; export default class HelloWorld extends React.Component<IHelloWorldProps, any> { constructor(props) { super(props); this.state = { items: [], }; } private search(): Promise<any> { const spSearchConfig: ISPHttpClientConfiguration = { defaultODataVersion: ODataVersion.v3 }; const clientConfigODataV3: SPHttpClientConfiguration = SPHttpClient.configurations.v1.overrideWith(spSearchConfig); var url = "https://xxx.sharepoint.com/sites/vmf-lab/_api/search/query?querytext='ContentType:Kvalitetsdokument'&selectproperties='Title,RefinableString05,CreatedBy,Created'&rowlimit=500"; //this.properties.siteUrl + "/_api/web/lists"; return this.props.context.spHttpClient.get(`${url}`, clientConfigODataV3).then((response: SPHttpClientResponse) => { if (response.ok) { return response.json(); } else { console.log("WARNING - failed to hit URL " + url + ". Error = " + response.statusText); return null; } }); } componentDidMount() { this.search().then((response) => { this.setState({ items: response.PrimaryQueryResult.RelevantResults.Table.Rows }); }); } public render(): React.ReactElement<IHelloWorldProps> { return ( <div className={styles.helloWorld}> <div className={styles.container}> {this.state.items.map(row => <div className={`ms-Grid-row ${styles.row}`}> <div className={`ms-Grid-col`}> {row.Cells.map(col => <div>{col.Key} - {col.Value}</div> )} </div> </div> )} </div> </div> ); } }
Hope it works.
Not yet but I'll keep on digging. Getting close now.
I had to create my own version of the web part to test the code. This works for me :-)
import * as React from 'react'; import styles from './HelloWorld.module.scss'; import { IHelloWorldProps } from './IHelloWorldProps'; import { escape } from '@microsoft/sp-lodash-subset'; import { SPHttpClient, SPHttpClientConfiguration, SPHttpClientResponse, ODataVersion, ISPHttpClientConfiguration } from '@microsoft/sp-http'; export default class HelloWorld extends React.Component<IHelloWorldProps, any> { constructor(props) { super(props); this.state = { items: [], }; } private search(): Promise<any> { const spSearchConfig: ISPHttpClientConfiguration = { defaultODataVersion: ODataVersion.v3 }; const clientConfigODataV3: SPHttpClientConfiguration = SPHttpClient.configurations.v1.overrideWith(spSearchConfig); var url = "https://xxx.sharepoint.com/sites/vmf-lab/_api/search/query?querytext='ContentType:Kvalitetsdokument'&selectproperties='Title,RefinableString05,CreatedBy,Created'&rowlimit=500"; //this.properties.siteUrl + "/_api/web/lists"; return this.props.context.spHttpClient.get(`${url}`, clientConfigODataV3).then((response: SPHttpClientResponse) => { if (response.ok) { return response.json(); } else { console.log("WARNING - failed to hit URL " + url + ". Error = " + response.statusText); return null; } }); } componentDidMount() { this.search().then((response) => { this.setState({ items: response.PrimaryQueryResult.RelevantResults.Table.Rows }); }); } public render(): React.ReactElement<IHelloWorldProps> { return ( <div className={styles.helloWorld}> <div className={styles.container}> {this.state.items.map(row => <div className={`ms-Grid-row ${styles.row}`}> <div className={`ms-Grid-col`}> {row.Cells.map(col => <div>{col.Key} - {col.Value}</div> )} </div> </div> )} </div> </div> ); } }
Hope it works.
- Franck CornuOct 24, 2017Brass ContributorTotally agree!
- Franck CornuOct 24, 2017Brass Contributor
Ok I didn't see this, my bad. I had similar issues with typings due to the version of TypeScript and React used by the SharePoint Framework.
I suggest you to update your SPFx generator with the latest drop (1.3.0), and use the latest version of sp-np-js. Don't forget to wipe your node_modules folder before.
- Maggan WåhlinOct 24, 2017Iron ContributorThis is really good advice, I have tried the library and it is awesome 😊. Why is there not more information out there in this? It should be top ranked by Google 😊
- Mike JansenOct 24, 2017Iron Contributor
Hi Franck Cornu, Thanks
It is never too late to see a different approach. Will have a look at your example.
As a matter of fact, I even tried it before but got stuck. You can see my problem here https://techcommunity.microsoft.com/t5/SharePoint-Developer/SPFX-gt-pnp-sp-reference-in-React-project/m-p/115349#M3522
- Franck CornuOct 24, 2017Brass Contributor
Hi Mike Jansen,
Why not use the sp-pnp-js library to play with SharePoint search? This library offers you built-in methods and typings to manipulate search results, refiners and so on more easily. Maybe it is little bit tool late but here is a working example using this library with react and SPFx. This sample using a generic TypeScript interface to map results:
https://github.com/FranckyC/sp-dev-fx-webparts/tree/react-search-refiners/samples/react-search-refiners
Hope it could help!
- Mike JansenOct 24, 2017Iron Contributor
Maggan WåhlinOne more question.
Can you tell me how to filter data here:
{row.Cells.map(col => <div>{col.Key} - {col.Value}</div> )}
Suppose I only want to show "CreatedBy" an "Created"
If col.Key = "CreatedBy" { }
Something like that?
EDIT:
Got it:
{row.Cells.map(col => { if (col.Key == "CreatedBy") { return <div>{col.Key} - {col.Value}</div> } }
- Mike JansenOct 24, 2017Iron Contributor
Again thanks a lot for all your help and patience.
This gets me started using the SharePoint framework. I try to migrate an SharePoint classic application to the modern variant. The old one heavily uses CSWP and display templates. Now I have one of the most important techniques covered. Diving into layout (UI Fabric) now.
- Maggan WåhlinOct 24, 2017Iron ContributorGlad it worked :-)
- Mike JansenOct 24, 2017Iron Contributor
Got it!!!
Was some quote pasting problem.
Had '${url}' instead of `${url}`
Thanks a lot!!!
- Mike JansenOct 24, 2017Iron Contributor
I'm not very lucky. Getting an error again.
For sure the url is ok but it looks like it is not passed in a decent way.
WARNING - failed to hit URL https://Blabla.sharepoint.com/sites/bla/_api/search/query?querytext='ContentType:BLA_matters'&selectproperties='Title,RefinableString10,CreatedBy,Created'&rowlimit=500. Error = Not Found react-get-items-web-part.js (214,17) HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier). (Fetch)GET - https://Blabla.sharepoint.com/sites/bla/_layouts/15/$%7Burl%7D
When I copy the url from the source code and paste it in the browser it's working.
- Maggan WåhlinOct 24, 2017Iron Contributor
It was a way to get a hold of the context object, maybe there is another way of doing it, but here it goes:
HelloWorldWebPart.ts:
public render(): void { const element: React.ReactElement<IHelloWorldProps > = React.createElement( HelloWorld, { description: this.properties.description, context: this.context } ); ReactDom.render(element, this.domElement); }
HelloWorldProps.ts:
export interface IHelloWorldProps { description: string; context: any; }
- Mike JansenOct 23, 2017Iron Contributor
One, I hope, last question.
"return this.props.context.spHttpClient"
I get an error on "context" Saying it does not exist on type .....
I guess it must be in my "----Props.ts"
What is you line?