How to use webpack to manually test react components? - node.js

I know we should use unit tests for our reactjs components. But what I also want, is some way to manually test our components in isolation. Because we are working on small sprints in which we must deliver some finished component before having the page that first uses that component. And I want to see that full component really working (i.e. test integration with css and sub-components).
So to start with, I would like to see that new component rendered in black page that doesn't require that component directly, but to take that component name/path from a query-string parameter. And then I plan to add to that page some generic component configuration (e.g. a textbox with json representing the props to pass to that component).
The first problem I'm facing now is about how to configure webpack, webpack-dev-middleware, or webpack-dev-server to be able to load a component passed by parameter.
Anyone know how to that? Or a better way to handle this?

I would try something like this:
Set up an entry point that uses require.context.
Invoke require within that context based on your querystring. You should have you React component now. Render that through React.
In order to generate the test controls I would include the meta within the component using JSON Schema. The form controls could be then generated using some form generator such as plexus-form or tcomb-form.

Related

Spartacus: Override cx-update-profile to add/modify input fields in PersonalDetails

Am trying to modify Personal details page in myaccount, i want to add new input fields, remove some existing input fields, how to achieve this, appreciate your help. Thanks.
General way of replacing a CMS component
find the flexType of the component, or the component typecode from the /pages request in your browser tools - network tab.
generate a module and a component with the ng-cli (ng g m your-profile-details followed by ng g c your-profile-details
configure your component to be used https://sap.github.io/spartacus-docs/customizing-cms-components/#page-title
copy the entire HTML from the OOTB source code
in the *component.ts file, you extend the OOTB component extends XXComponent
sometimes you have to copy the implementation as well, depending on the visibility of the attributes / functions in the OOTB component.
Run yarn run start and verify if your component is now in use!
Modify your component HTML to your liking.

Dynamic Component Loader vs. Lazy Loading

What is the difference between Dynamic Component Loader and Lazy Loading? I need to build an application that needs to have an <router-outlet> at the root of the application. My Problem is that I don't know how to implement a Component that renders Child-Components according to data, dynamically. My current approach builds up on Dynamic Component Loader, but using this technique I have issues concerning tracking my location, navigate back, etc.
Is there any best practice for using "multiple <router-outlets>" (e.g. Lazy Loading)?
Thanks!
Loading components dynamically is not related to Lazy Loading.
Lazy Loading is a way to split up your application into modules that are loaded lazily (in the background) instead of loading your entire application at the start. This helps your app load more quickly so the first page is rendered sooner than it would if you did not use lazy loading.
For example, you might have a settings menu which loads various settings, but you don't expect users to visit that menu very often, so you put all the components for settings into a module and then you set that module to be loaded lazily (in other words none of that code needs to be downloaded unless a user actually visits the /settings route).
All angular applications must have a <router-outlet> at the base component (usually AppComponent). This is a requirement of all Angular applications.
You may want to consider also using auxiliary routes - these are optional, and allow you to load components in different 'places'. You can read about them here
Alternatively you can (for simple cases) just use ngIf, like this:
/app.component.html
<div *ngIf="isOption1(); else Option2">
<my-option1-component></my-option1-component>
</div>
<ng-template #Option2>
<my-option2-component></my-option2-component>
</ng-template>
/app.component.ts
public isOption1: boolean {
return <some test that returns true or false>;
}
So based on the logic the method isOption1 returns, the user will see either Option1 component (when true) or the Option2 component (when false).

How to pass context to a React/jsx view?

I'm new to React, and I'm trying to figure out some basics. In other template engines such as EJS or Jade, you are able to pass in a context variable when you are rendering the view file in your routes/controller file. However, I have not found any way to do this with React/jsx. I should note that I am working with Express.
I am actually uncertain if jsx is a view engine, or if React somehow was one built in. In either case, I do not know how to pass context from the server to the view file.
For example, if I wanted to load profile information (that is stored on the server/backend), how would I pass that to my front end jsx view file in React/jsx?
that's simple. There is a mess in MVC terminology, but I think it would be okay to say that React component is not just the "View", but "View + Controller".
As a direct analogy to the templating engines, component's render() function is your template. And component.state (which is local to the component) and component.props (arguments received from the upper component) both can be used as a "context".
If you want some really close analogy to the React component in the conservative part of the JS world, it's Backbone's View (which is again the view + controller if we use original MVC terminology; as I told - it's a mess). Conceptually, it's the same thing. JSX is used in render() instead of EJS (or whatever), that's it.
Btw, React's context concept is something different. Think of it as
props which are visible to the whole component subtree starting from
the component where the context is exposed.
For example, if I wanted to load profile information (that is stored on the server/backend), how would I pass that to my front end jsx view file in React/jsx?
In the simplest case, you create the top-level React component, which would load the stuff you need on mount (componentWillMount()), put it to its local state when you'll receive the response from server (this.setState(...)), and pass elements of its state (this.state) down to the subcomponents as props (<List items={ this.state.items } />) in its render() function.
Whenever state is modified with this.setState(...), the whole component subtree will render again. That's how it works. In the simplest case.

Is there a way to use a javascript object as a custom control property?

I'm currently building a custom control to be used as an application's view navigator (classic OneUI style). First of all: this is a 8.5.3 based project, and unfortunately there's no way to use Extlib stuff or other extensions / plug-ins. So we have to build all the tricky stuff ourselves using only what came "out-of-the-box" with 8.5.3.
I'd llike to build my navigator using a repeat control containing <xp:link> controls. Datasource could be an array of javascript objects where each single object would look like this:
var navEntry = {"entryLabel" : "label-of-link",
"entryTarget" : "target-url-of-link",
"entryStyle" : "style-to-emphasize-selected-link"}
Each array element then would describe a single navigator entry.
Since the navigator will be used in all possible "DominoView" Xpages it yould make sense to build the array of JS objects at the Xpage level and then pass that info into the custom control.
I'm aware that there are multiple ways to do this, and one could be "Custom Control Properties". If there was a way to pass my JS object array.
(Hope I could make clear what I'm trying to do here...)
That object looks like a HashMap to me really. You should be able to pass that in to a custom control via custom property if you use the type java.util.HashMap I'd think. You'll need to type it in I'm sure. I've passed custom objects in by using java.lang.Object.
The custom control will get loaded during the Page Load event, and usually properties have to be available at that point. If they're loaded during the Render Response phase, that's too late. So your SSJS object will need to be Compute on Page Load.
To use contents of a repeat control, you would need to set repeatControls=true, otherwise the repeat is only built during render response. Until then it's just a single set of controls with no data in them. However, Im pretty sure repeatControls="true" means you only get the number of rows you define. You can't change it via a pager.
You can manually define the type of the custom property. For a standard SSJS Object you use "com.ibm.jscript.std.ObjectObject", for a SSJS Array you use "com.ibm.jscript.std.ArrayObject" etc. As editor for the custom property, I set the string editor ("String value").

developing library controls for xpages

I' working on a library control for Xpages and need some help in creating.
I would create a control which reads a configuration file and creates controls in a table, controls like Editboxes, checkboxgroups and so on.
so and now to my questions:
could I initiate controls from the Exlib or must I implement them all by my self?
if I could use them from the Exlib could anyone explain me how?
I hope its clear what i mean if not please ask me for further informations.
When creating your own components, if you're closely replicating some behavior that is already in an extension library component, I highly recommend you extend that component and just add what's needed to accommodate your different functionality. This makes things much easier and you don't have to code around every little scenario that the component might be placed in.
But, if you are developing a component that is nothing like any of the extension library or core components then just ensure your component extends UIComponent or UIComponentBase. If going this route, you'll also need to create your own renderer which extends Renderer. This is what will build the on-screen representation of your component. Again, if there's already something in the core components or extension library components that closely mimics what you need then make your renderer extend that renderer. Also, don't forget to include the renderer definition in the faces-config file and the component definition in the xsp-config file or your component won't work.
As for initiating controls from the extlib.... I assume you mean can you inject them onto the page at runtime. If so the answer is absolutely yes. To add an input text field to the page where there is a container (i.e. panel, div, span, whatever) with an ID of "someContainer"
XspInputText input = new XspInputText();
input.setValue("someValue");
input.setId("someID");
UIComponent container = FacesContext.getCurrentInstance().getViewRoot().findComponent("someContainer");
container.getChildren().add(input);
To see the api for all of the core and extension library components take a look at the XPages Controls Documentation. For a more complete tutorial on creating your own components take a look at my blog for creating a custom component inside an nsf, the steps are pretty much the same for putting them into a library:
Part 1,
Part 2 and there is an example database in the Part 2 post.

Resources