How to use React with PowerBI custom visual - reactjs

I'm trying to progress a Power BI Custom Visual react sample to the stage where it can access the dataViews of the parent visual in the React component.
The sample in question is https://github.com/ignatvilesov/powerbi-visuals-react-sample
Answers to this question may not require expertise in Power BI custom visuals, knowledge of React may be sufficient.
In the Update method of the visual it create the calls ReactDOM.render like this: ReactDOM.render(React.createElement(App), this.element);
This works and creates a component that allows the react component to display elements in the visual.
When I attempt to pass the data options: VisualUpdateOptions like this: ReactDOM.render(React.createElement(App,{options} ), this.element); , I am finding problems.
I don't understand how to get the options object using props, I've tried a variety of things, here is a sample of my attempts at an App.tsx
module powerbi.extensibility.visual {
export class App extends React.Component<any,any> {
constructor(props: VisualUpdateOptions) {
super(props);
}
public render() {
var message = "";
if (this.props == null){
message = "no data"
}
else
{
message = "got data"
}
var message2 = "";
if (this.props.dataViews == null)
{
message2 = "no dataview"
}
else
{
message2 = "got dataview"
}
...
I get data ok, message2 always gives me no dataview.Any advice would be greatly appreciated, I have great ignorance in this area and seek enlightenment :-)

I think you should try to pass the props object to create element inside the visual.ts (where you create an instance of the react app). Something like this:
ReactDOM.render(React.createElement(App, {"yourProp": "props"}), this.element);
Console log the props as you are doing now, you should see them.

Related

Sentry for micro frontends

Is there any possibility to initialise Sentry twice on a page? Use case would be error tracking for parts of the app that are inserted as microfrontend.
So errors happen in this part of the app should be send to the teams own sentry project. I also wonder if there is any way filter the errors so only the ones that are relevant for the microfrontend are send and others are filtered out. Could we use reacts error boundaries for that?
Looks like there is a way to initialize something called Hub with a second dsn like this:
import {BrowserClient, Hub} from '#sentry/browser';
const client = new BrowserClient({
dsn: 'micorFrontEndSntryInstance'
});
const hub = new Hub(client)
this hub can passed to an ErrorBoundary wrapping your component.
In every componentDidCatch we can then send the error to the micro frontends sentry:
componentDidCatch(error, errorInfo) {
this.props.hub.run(currentHub => {
currentHub.withScope((scope) => {
scope.setExtras(errorInfo);
currentHub.captureException(error);
});
})
}
All the code is from this example implementation.

React Firebase Callback

I started learning React using Firebase about one year ago, and it's all going pretty well, I guess. However, ever since I started writing, I really miss mastering the art of callbacks like I did with Swift.
I feel that there's barely any information that's going straight to the point regarding callbacks and Firebase using React. For instance, there has been so many times I want to be able to use callbacks, but have ended up writing numerous extra functions to perform the exact same task. For instance, I want to be able to call a function, and then return a value inside a Snapshot.once. But how?
You see, this is an example of an issue I'm facing at this very moment. I'm currently mapping out a list of users on my website, with the following information: firstname, lastname and companyId. Upon display, I want to be able to verify that the companyId does in fact exist in a separate table called 'Companies' structured like this:
Companies -> uniqueCompanyId -> information
I know that I can't return values in an async function, but this is what I am thinking about:
isCompanyVerified(input){
databaseCompanies.child(input).once('value', (snapshot) => {
if(snapshot.val().isVerified){
return true;
} else {
return false;
}
})
}
<div>
allUsers.map((singleUser) => {
return(
<p>{singleUser.name}</p>
<p>{this.isCompanyVerified(singleUser.companyId)}</p>
)
})
</div>
It would really mean the world to me if someone could explain to me how I would do this the correct way, or at least point me in the right direction. The problem is that I honestly don't know where to seek information.
I'm used to having code structured with having all networking/database functions in one file, like I did in Swift called ex. 'Networking.swift'. And then do function calls that I fetch from the specific file. Using React, I have ended up having all of my code in each Component, resulting in a lot of duplicated code, a lot of extra work and making it all look unstructured.
I'm fairly familiar to the syntax right now, and I do believe I have learned a lot, yet - I feel that I do numerous things the wrong way, and still have a lot to learn. Where would be the best place for me to learn to really master React? Going from intermediate to an 'experienced' (writing and structuring React code like it's supposed to be done).
All help is appreciated. I'm making this post as I really want to put in the effort to learn.
You cannot directly write the dom in react like this. The dom is not being re-rendered in this case. Store the verification data in a state and the dom is being re-rendered as soon as the async data arrived.
SOLUTION 1
This is an implementation of a single UserItem component:
UserItem.js
class UserItem extends React.Component {
state {
isUserVerified: false
}
handleVerified = snapshot => {
this.setState({ isUserVerified: snapshot.val().isVerified })
}
componentDidMount {
const {userId} = this.props;
databaseCompanies.child(userId).once('value', this.handleVerified)
}
render() {
const { isUserVerified } = this.state;
return (
<div>{isUserVerified ? 'verified' : 'not verified'}</div>
)
}
}
UserList.js
...
render(){
allUsers.map(singleUser => <UserItem userId={singleUser.id} />
}
SOLUTION 2
If you'd like to list all the users, get a snapshot from the complete users object
componentDidMount {
databaseCompanies.child('users').once('value', this.handleStoreUsers)
}
This will result something like this in the state:
state = {
users: {
_key1: { id..., verified: true },
_key2: { id..., verified: false }
...
}
}
And map trough them.

ReactJS - Front-end form error handler/validation

I'm building a simple donation app in ReactJS. Here is a working version here:
https://stackblitz.com/edit/react-grzdgz
I've never done form error validation though. So if someone doesn't fill out a field, I'd like an error message to pop up, which says something like "this field must be completed".
I've been trying to follow this tutorial:
https://learnetto.com/blog/how-to-do-simple-form-validation-in-reactjs
But I'm kinda getting lost, about how I can pass these functions/error messages, into my form, which sits in a seperate module. In the demo, everything sits in one file.
But in my app, my form sits seperately to index.js. So I link to it in index.js.
I'm almost there, I just need some help connecting everything up.
Can anyone help me get form error validation working?
The error handling functions all sit here:
https://stackblitz.com/edit/react-grzdgz
The form itself sits here:
https://stackblitz.com/edit/react-grzdgz?file=components%2FForm.js
And some form errror heres:
https://stackblitz.com/edit/react-grzdgz?file=components%2FFormErrors.js
Any help would be great!
Thank you!
On the submit, I would have a method called: validateFields, which would validate all field like you want (instead of using the default validator of html, which doesn't work on some browser). In the method, I would save all the field with an error.
If the error list (or object) is not empty, you use an alert or popup react-popup
If there are no error, you can call submit method.
Basically, it would look something like:
export default class DumbComponent extends React.Component {
state = {} // all your field value
validateField = () => {
let error = []
//Validate all your field
if (error.length === 0) {
this.submit()
} else {
this.showError() // You decide the way
}
}
render() {
return (
<Form>
<FieldOne />
<Field2 />
<SubmitButton onSubmit={this.validateField} />
</Form>
)
}
}
Hope it answer your question!

Openlayers ol-ext select multiple features to transform

I am using the ol-ext extension for Openlayers, which is awesome.
The piece I am interested in is the Transform interaction, I have it working inside a basic React example here: https://jsfiddle.net/mcneela86/umrz7dd1/
This is the extent of the component so far:
class Select extends React.Component {
static contextTypes = {map: PropTypes.object}
componentDidMount() {
this.select = new ol.interaction.Transform();
this.context.map.addInteraction(this.select);
console.log(this.select);
}
componentWillUnmount () {
this.context.map.removeInteraction(this.select);
}
render() { return null; }
}
My question is, is there a way I can select multiple features at once?
The Transform interaction is assumed to handle only one feature.
More than one could be used but I need use cases to see what's happened (should each feature rotate individualy? around which center? etc.).
You can ask for a enhancement on the github page.

Remove item using its location or key in Firebase React

I have a simple react application and I am able to add data to it, but I am not sure how to remove/update data.
the main problem is in getting the part where I tell firebase which data to remove. how do I tell that to firebase.
I am using react.
I have been trying out different things but it's just not working
handleRemove(){
console.log('you reached handleRemove function');
var ref =firebase.database().ref('items');
ref.on('value',this.handlegetData,this.handleErrData);
['items']['KpAmo20xP6HPXc7cwjY'].remove();
//itemsRef.remove('KpAmo20xP6HPXc7cwjY');
}
Please tell me how to do this.
My firebase database looks somewhat like this
You need something like that to remove value :
handleRemove() {
return firebase.database().ref('items').child('ITEM_KEY').remove();
}
or something like that to update value :
handleUpdate() {
var updates = {};
updates['/id'] = 1;
updates['/title'] = 'Apple';
return firebase.database().ref('items').child('ITEM_KEY').update(updates);
}
(In your screenshot items is equal to firebase-test)
Here the Firebase Realtime Database documentation.

Resources