Web components loading unknown component - javascript

I am creating an application where I want to load the different components from a string (which will be represented in my database).
So I've written a test (before getting the data) where I test the option for loading these dynamically and without me knowing exactly which component to load at a given time:
So far I've succeeded with the dynamic import:
import(`${this.sdkbtnString}`);
Now I've tried a few methods to place a tag that I don't really know what is ahead of time. For instance I attempted:
<${this.sdkiconbtnString}></${this.sdkiconbtnString}>
This naive approach did not work.
Then I attempted to see if I could get something from using:
const t = async import(`${this.sdkbtnString}`);
However I can't really use this for anything as it just returns a module definition.
So how can I load a tag where I don't know exactly what the tag should be. Also what do you feel about this approach is there a better way?

Related

Visual builder to work with manually hard-coded templates/components

I wonder, is it possible to create a visual no-code builder to work with JS components (e.g. React JSX) if them are manually hard-coded before?
Let me explain what I mean.
Suppose a simple React component pages/index.js previously written by a developer manually:
function HomePage() {
return <div>Welcome to Next.js!</div>
}
export default HomePage
How can we change such a component in the front-end using a visual builder?
For example, we want to add a new HTML element (e.g. H1) inside the existing div.
As I can understand, the builder first needs to know in which JS file the HTML markup is stored to update it. So we can add id="homepage" to the div first and then store a relation as a config like
{"homepage": "pages/index.js"}
And now if we add a new element inside <div id="homepage">, the builder adds the element to the DOM of the div at the client, then takes the whole updated DOM of the div and writes back to the file index.js according to the config
Ok, but the file contains not only HTML markup - it's JS (React) code.
How to keep all the JS code e.g. function HomePage(), return, export default and so on ?
As an option, we can separately load all the JS code as HTML including non-HTML code as #text nodes. Then update the DOM and re-write everything back to the file.
But it sounds complicated and may cause unexpected issues.
So what solution would be the best?
Or maybe there is a ready React-specific solution?
Or maybe it's a bad idea at all to parse and re-write manually hard-coded components by visual builder and the only solution is to store everything as JSON like "homepage":{"div", {"class":""}, "Welcome..."} which is more easy for re-writing ? (but requires a new render)
It depends
I believe the answer that you are looking for very much depends on the level of flexibility that you want your no-code builder to have.
Depending on that, your project could benefit of the trade-offs and advantages of different solutions.
Let's briefly remember that basically a React component will need some props that then will be taken through a render template and output a working HTML. This is assuming a basic case where you don't need your react components to be smarter. Additionally, JSX is just sugar coating over function calls, so you could basically just compose functions to output a React component independently of using the JSX syntax. Hence no need to declare HTML, just changing the output of your no-code tool to JS instead of HTML.
For example, if you can modify how the no-code tool render, you can specify that when moving an element inside another you basically:
Highly Flexible & Customisable
In a highly flexible setup, I will recommend going through the last option you numbered, having a Data-Driven UI is the most common of the cases for complex systems. For example, Figma has an option to export the designs as react components, you can read how they do it here. Basically they take the tag output from figma which is a JSON of tags and create some React componets using templates. If you define "you own UI language" you could have quite a good control over what blocks you can build and define the way of interacting with them (e.g. adding a img component could be quite easy if you know the props and what it needs to render, then creating a React template for it is easy).
Limitations: you require to plan quite well the API of the parser and interaction between different sets of items.
Simple no-code builder
For simpler scenarios you could go with the first approach that you mention, you won't even need to add ids, some tools like React Developer Tools can already inspect the VirtualDOM to understand which part of the render belongs to which React Element (using react internals, which could take some time to understand, but for example you can inspect in the rendered how they use the data-reactid for identification). Knowing this, you can already define the template functions for the render() method (so the JSX output), and separate it code wise, so that when you generate the code, the HTML template is split from the React code as much as possible.
Silly example of how it could look:
// htmlBlockTemplate.js
export const helloPageTemplate = (props) =>
`<div> <h1>${props.title}</h1> </div>` // This can be generated from the `no-code`
// page.jsx
export const Page = (props) => {
return helloPageTemplate(props)
}
Using functions it could look like:
const Page = (props) =>
return React.createElement('div', null,
React.createElement('h1', title: prop.title, `The title ${title}`)
);
}
Limitations: eventho you could, adding custom components (like another React Component or a web component), it becomes more difficult since you will also have to deal with the import graph and probably.
Inevitably you will need to tweak how the render of the component works (rather by creating a parser from your UI language, or changing how the react component is written. If you have a good control of AST, then writing a parser for either of the cases should not be a problem.

Share global variables between aspx and Vue pages

Before anybody starts screaming at me for using global variables, I have a few things to say:
This is only for one variable and will only be used temporary (my estimates says that it will be gone within one year)
I'm open for suggestions on how to solve this a better way
Our project has a bit of a unusual setup. We have an old ASP.Net website, that we are slowly converting to VueJs, page by page. Due to this, we are using UMD
Currently Vue is used for the menu, showing content, etc. When showing an old aspx page, we are using iframe. My goal is for my Vue to be able to catch events thrown from the open aspx page
For this I thought the mitt emitter would be perfect for the job. I'm using it in my Vue project already
On the code side of things, I have the following:
I have a Toolbox.js file, where I try to keep my global variable
var emitter;
async function ClickFromOldPage()
{
emitter.emit('test');
}
In mounted in my vue file (the first thing that opens) I'm setting the global variable
mounted()
{
window.emitter = window.mitt();
window.emitter.on('test', this.Test);
},
And then I have an aspx page that calls ClickFromOldPage
Both the vue file and aspx file is loading Toolbox.js like this
<script src="../Vue3/Javascript/Toolbox.js"></script>
From what I could gather around the net, this should do it, but emitter is undefined when calling Toolbox from the aspx page
Another way was by using top to set/get variables, but this gives the same result
I also tried localStorage, but this can't handle complex objects like the emitter
The only other way to handle this challenge I can think of, is by using cookies or localStorage, where the aspx page writes 'Clicked' (or whatever), then have a function in Vue that checks for said data every second or so. This doesn't sound like a good solution, but the only solution I can come up with
Any other ideas?

NestJs: Is there a way to generate a resource, already wired to a TypeOrm entity?

I'm playing around with NestJs, for the purpose of automating REST API creation as much as possible. So far, I do not see any quick way to create a fully functional resource.
For example, if I use the Nest CLI like this:
nest g resource
And call my resource "posts", I get a module, a controller, a service, dto's and an empty entity
In order to make it functional, I would need to manually go through every method of the PostsService, remove the placeholder, and wire it to the corresponding entity method. For example, this needs to be altered:
findAll() {
return `This action returns all posts`;
}
to:
findAll(){
return this.postsRepository.find()
}
Not to mention, that I need to add various decorators and imports. In my opinion, this undermines the whole idea of CRUD generator. A lot of files are created for me, but they need to be altered.
Is there any way in Nest to create a fully functioning resource(of course i would still need to manually set the fields of the entity), with all parts wired to each other correctly?
I also tried to find something similar. And this is the best what I found https://github.com/ashinzekene/generator-nestjs-app
I think if such a thing existed, then it should have been mentioned in this repository. https://github.com/nestjs/awesome-nestjs
But it's not. Maybe I'm wrong 😑
The purpose of nest isnt to get up and running asap -> You would probably want to use something a little bit more user friendly / or one with a more guided workflow.
in terms of what the generator is giving you...
Controller Only deals with the request / response being recieved and sent... it doesnt have any other type of functionality...
DTO think of it like an interface but with more functionality , as you can add data-validation / etc to make sure the request object is formated properly...
Service Exposes the methods that contain all of our business logic. for a crud app, this would be where your actual get post put patch delete would be ... and how the data us modified in your db. Then once this finishes it would return the response if any to the controller which sends the info out.
this is helpful for many reasons... one if our project has 200 endpoints and 40 people working in different teams you dont want each team to have a different way of doing things, also you want it to be clear where each thing is... if you endpoints need to be changed , you simply go to your controller... if the logic needs to change, you go to that service etc...
The Purpose of nest is to give you a framework for extremely modular apps / essentially everything decoupled..
think of it in terms of an express... you could have a single page express app that just has everything in one place... or you could have every single thing on it's own area...
esentially nest doesnt do anything crazy that express cant, it's just the underlying inversion of control (the .main file which calls the app.module which builds all the different pieces that are needed for that endpoint / app / service / or etc.)
If you just want to use nest because it seems shiny , id consider looking up something like fastify or / even appsmith / or something else like that...

React - Parse HTML string and insert components at particular places within it

I'm working on an app for a client who wants to display Zendesk Support article data with richer content than the API/tool supports. The API, powered by a basic WYSIWYG editor on Zendesk, is able to serve up an HTML blob with <p> and <img> and <a> tags. But it's unable to, say, easily embed a video, show an image gallery, or link to another location in the app without necessitating a hard refresh.
So we decided to build out a small amount of DSL syntax whereby the client could type something that would be parsed on our app and turned into the richer content. For example:
[[ video src="youtube.com/whatever" ]]
might, on our app, be parsed out, and replaced with an iframe embedding that video directly in the article.
I've got the above example working just fine, using all sorts of fun/problematic RegExp magic.
I'm aware that parsing HTML with RegExp is a major anti-pattern, and I'm getting around it by not really parsing HTML per se -- I'm just looking for [[...]]).
Basically, I parse each code out, determine what to replace it with, pass back that component, and then call ReactDOMServer.renderToString(replacementEl) to insert the resulting HTML into the article HTML string, which is then rendered to the page using dangerouslySetInnerHtml.
This is working great, despite all the obvious messiness issues. (I know, but the client wants a very feature-rich solution, and wants to use the Zendesk API).
Here's the problem: This solution only works when rendering HTML. It doesn't work when I try to render, for example, a <Link> (from React Router) or a home-made <Gallery /> component.
So I'm trying to figure out if there's a good way to do this. One that ideally doesn't involve going full RegExp on the HTML blob (which is obviously a mess).
I'm guessing that the solution will involve removing the codes, converting the code-free HTML string into actual React components (as opposed to just spitting the string into another element), and then, based on some sort of ledger of where the short codes go in this new React component, inserting the contents into the page.
But I'd appreciate some suggestions if anyone has encountered a similar problem. I want to do this in a way that isn't totally crazy and brittle, though it's obviously an inherently messy problem.
EDIT: To clarify, when I say it doesn't work, what I mean is that the JavaScript associated with the React components doesn't run. If I replace a code with a <Link to="whatever" />, for example, ReactDOMServer.renderToString successfully turns that component into its final HTML (an <a> tag), but nothing happens on click of that tag, because the JavaScript that's actually changing browserHistory on a regular click just isn't run.
So maybe the more pointed question is:
Is there a way to insert React Components into an HTML string in such a way that they retain their JavaScript functionality and don't just become HTML?

Reactjs server-side rendering seems to not change a thing on the client side

I'm trying to optimize my big ReactJS project and I've stumbled upon a conclusion, that React code in the browser is not taking any advantage of server rendering. I'm sure that server-side rendering is working properly, I can see data in the page source returned from server, with all the data-reactids.
Setup: server-side code is rendered in Node. React version 15.0.1. I'm using ClojureScript and rum, but it shouldn't matter in the end
Test environment: Using React.addons.Perf, wrapping it around initial mount on the client side.
Test 1: proper server-side rendering
Total time around 1.8s, Inclusive Time of root component about 1.5s. React.addons.Perf.printWasted() shows nothing.
But what is the most puzzling part for me is that React.addons.Perf.printOperations() shows one operation: "set innerHTML" with the whole app's html (e.g. <div data-reactroot=\"\" data-reactid=\"1\"><div id=\"wrapper\"...). Like the whole server-side rendering result was discarded and this client-rendered HTML is inserted in the DOM, probably causing re-rendeding.
Test 2: invalid checksum; by purpose I've added some extra attribute on the server-side only.
Of course the "React attempted to reuse markup in a container but the checksum was invalid." warning appears.
However, everything else is similar to the Test1 above! Similar times, and also the single "set innerHTML" operation. This confirms for me that even if checksum is correct, React ignores pre-rendered markup (because it seems to do the same operations in the similar times whether checksum is correct or not)
Test 3: turned off server-side rendering; returning empty mount-point container.
Times about 0.2s longer. The only real difference now is that there are many operations, most of them update attribute or update styles and one set innerHTML with {"node":"<not serializable>","children":[],"html":null,"text":null}.
Question/Problem
I don't know what to think about it. React advertises SSR as a way to speed up application bootstrap, as it does not need to generate DOM tree again (or rather: insert it in the document; it still need to be rendered in order to compare checksums, right?). But for me it seems like nothing is gained.
Can someone who is successfully utilizing SSR tell me what are his/her reading in printWasted() and printOperations()? The only thing I managed to find was this audit: https://github.com/reddit/reddit-mobile/issues/247#issuecomment-118398416 (only printWasted, though) - none of my tests shows any entires in printWasted.
Well, it all was simple: after upgrading to React 15.4.2 Test 1 shows no operations, as I expected it to in the first place. So in the end it all was issue of (not so) old library version. Yet the times of mount are still very similar.

Categories

Resources