Meteor: inject html into client-side file on startup - javascript

Using the SSR and inject initial packages,
I currently have the following server-side code:
Meteor.startup(function() {
.....
Inject.rawHead('importList', function(imports) {
return imports = Blaze.toHTML(Template.imports);
});
});
This injects a list of html imports into the head, and works perfectly.
I'd like to modify the function so that the code is injected into /client/imports.html instead of into the head... can this be done?

Looks close to this solution. Try this in the client folder of Meteor or use if(Meteor.isClient) for compactness:
Inject.rawHead('importList', function(imports){
return imports = Blaze.toHTML(Template.imports)
})
Meteor.startup(function(){
//...
})

Related

ExpressJS backed with mix of ejs and React frontend

I currently have a NodeJS application with an Express backend and all the frontend implemented with EJS. An example route looks like this currently:
router.get("/:name&:term", function(req, res) {
Course.find({ courseName: req.params.name, courseTerm: req.params.term }).populate("students")
.exec(function(err, foundCourse) {
if (err) {
console.log(err);
} else {
console.log(foundCourse)
res.render("courses/show", { course: foundCourse });
}
});
});
I have a lot of the pages of the website already implemented following the example route above. So the structure looks something like:
localhost:3000
-/courses
-/show
-/review
-/professors
-/show
-/rating
...
But I recently took a React course and want to use React for new pages like localhost:3000/groups
Is there a way to use React for some pages and still have EJS pages that I currently have? or do I have to rewrite all the EJS pages to React components? I'm still very new to web dev so any advice would be highly appreciated.
From my understanding, I would have to let the React app catch only certain requests/routes but I am not quite sure how to do that.
To answer this question thoroughly I'd have to write a small book, so I only show a basic case where the code is rendered client-side. I also assume that you know how to transpile jsx to js, so I'll treat all react files as already transpiled (that is all <> are converted to React.createElement()).
First, you have to create a route that will be handled by react (/groups), (I assume that you'll use some data for the rendering as in your example):
router.get("groups/:name&:term", function(req, res) {
Groups.find({ groupName: req.params.name, courseTerm: req.params.term }).populate("students")
.exec(function(err, foundGroup) {
if (err) {
console.log(err);
} else {
// here will be the react rendering code
}
});
});
Assuming that you have react code in index.js, you have to add it to the html code as well as data required by the app:
router.get("groups/:name&:term", function(req, res) {
Groups.find({ groupName: req.params.name, courseTerm: req.params.term }).populate("students")
.exec(function(err, foundGroup) {
if (err) {
console.log(err);
} else {
res.send(`<html>
<head>
<script>
const initialData=${JSON.stringify(foundGroup)};
</script>
</head>
<body>
<div id="react-root"></div>
<script src="index.js"></script>
</body>
</html>`);
}
});
});
Your App should consume the data like this:
React.render(<App initialData={initialData}/>, document.getElementById("react-root");
This should get your react code up and running. Going further, you can use react-dom/server to prerender html on the server, and mix-in ejs file as a template in which you inject react code to utilize your existing codebase.
Is there a way to use React for some pages and still have EJS pages that I currently have?
Yes you can, react is just javascript.
You can use create-react-app for a single page and serve that from the route of your choice but keep in mind that your front-end won't become a SPA by doing this you'll just be serving a react app on a certain route.
A somewhat better approach would be to not use create-react-app and instead setup your custom webpack build process to convert jsx to javascript, write a minimal ejs template to include your transpiled javascript code into the HTML, and serve that template from a route.
Reactjs component can be part of your backend code when using SSR(server side rendering) which is much more complicated. Or you can use a express static server to serve reactjs app which is ready to deploy, then express will only be a simple the static file router.

How to run a specific jquery script after each page load?

My client sent me an HTML template that heavily relies on jQuery. The app itself runs on nuxt. I have a js file that contains a whole lot of $(function(){...}). Now I don't know how to run this file on each page transition.
So far, I have tried:
Creating a plugin inside plugins dir that looks like:
export default async ({ app }) => {
app.router.afterEach((to, from) => {
require('~/static/js/base-init.js');
})
}
here base-init.js has all those jquery code
Adding mounted (inside default.vue layout) but that doesn't work either.
Does anyone have a clue?
If you want to use your jquery file on nuxt just do this
Inside your nuxt.config.js add
npm i jquery
plugins: [
'~plugins/my-jquery-code.js'
]
And inside plugins/my-jquery-code.js
if (process.BROWSER_BUILD) {
const $ = require('jquery')
$(function() {
console.log('document ready!');
// do whatever you want with html and jquery
})
}
I'm refering to this link => https://github.com/nuxt/nuxt.js/issues/356
its work for me !
Good Lucks.

How to use function from NPM library in html.eex template

Using Phoenix 1.4 with webpack, I added "findandreplacedomtext": "^0.4.6" to my package.json file and installed the library.
Now in app.js I have import findAndReplaceDOMText from 'findandreplacedomtext'; and that allows me to use the library, but it only works within the app.js file. I want to be able to use the library in my view templates but whenever I try to use it in a template, I get an error in the console Uncaught ReferenceError: findAndReplaceDOMText is not defined.
This is what the code looks like inside of my template:
<div id="container">
This is a test.
</div>
<script>
findAndReplaceDOMText(document.getElementById('container'), {
find: 'test',
wrap: 'mark'
});
</script>
That throws an error in the console. But if I put the same javascript code in app.js below the library's import statement it works. How can I use the library inside of my view template and outside of app.js?
The error is in your js, you're selecting an element by id 'container' but it's a class, so it should be:
findAndReplaceDOMText(document.getElementsByClassName('container')
At the top of webpack.config.js I put const webpack = require('webpack'); so that in the plugins list I could put new webpack.ProvidePlugin({findAndReplaceDOMText: "findandreplacedomtext"}). This made it so that I could remove the import statement for the library from app.js.
Then, in app.js I put window.findAndReplaceDOMText = findAndReplaceDOMText; in order to expose the module outside of app.js.
Finally, in my template, I had to wrap the function in a content loaded event in order to make sure I wasn't invoking the function before it was loaded.
<script>
document.addEventListener("DOMContentLoaded", function(event) {
findAndReplaceDOMText(document.getElementById('container'), {
find: 'test',
wrap: 'mark'
});
});
</script>

External Javascript is not working in react.js

I am creating a react app using create-react-app. I have some external javascript libraries for template design in main index.html
<script src="%PUBLIC_URL%/js/jquery-2.2.4.min.js"></script>
<script src="%PUBLIC_URL%/js/common_scripts.js"></script>
<script src="%PUBLIC_URL%/js/main.js"></script>
<script src="%PUBLIC_URL%/js/owl.carousel.js"></script>
These JS files are working on first page when the application gets started. But these libraries are not working when redirect to other page from first page.
From what I understand, these files are rendering but their functions, variables, and methods are not accessible when the route is changed.
I am using react-router-dom v4 for routing .
I googled it and found a solution-
To render the JS libraries by ComponentDidMount() method
ComponentDidMount(){
loadjs('./js/main.js', function(){
loadjs('./js/common_scripts.js)
});
}
But even this solution is not working.
Please help to solve this issue.
Thanks
This is how i import Jquery into my create react app
Jquery:
first run npm install jquery
index.js
import * as $ from 'jquery'
window.jQuery = window.$ = $
see: http://blog.oddicles.org/create-react-app-importing-bootstrap-jquery-cleanly-node-js/
Alternativly you can attach the scripts to a window object and then call them as needed:
Try following steps:
including the external js file link in your /public/index.html
use the external library with prefix window.
for example, JQuery.
put following line in your /public/index.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>`
use it in your project:
window.$("#btn1").click(function(){
alert("Text: " + $("#test").text());
});
`
See this for more details:
https://github.com/facebook/create-react-app/issues/3007
You are using componentWillMount() instead of componentDidMount().
I think that is the problem here.
You can set that js files on window object and then you can access it by window.your_name to object..
You have to set that in index file
Try using import() inside componentDidMount()
The import() is self explaining.It just import's the JavaScript files.
import('your_URL')
Try to call event using window object. reference Link
const loadScript = (src) => {
return new Promise(function (resolve, reject) {
var script = document.createElement('script')
script.src = src
script.addEventListener('load', function () {
resolve()
})
script.addEventListener('error', function (e) {
reject(e)
})
document.body.appendChild(script)
document.body.removeChild(script)
})
}
useEffect(() => {
loadScript(`${process.env.PUBLIC_URL}/js/plugin.min.js`)
setTimeout(() => {
setTimeout(() => {
setLoading(false)
}, 500)
loadScript(`${process.env.PUBLIC_URL}/js/main.js`)
}, 200)
}, [])

Loading Handlebars from Javascript

I am writing an EmberJS project in which I want to load Handlebars templates from Javascript instead of creating them in the html file.
Here's the code currently like:
<body>
<script type='text/x-handlebars' data-template-name='template1'>
...
</script>
<script type='text/x-handlebars' data-template-name='template2'>
...
</script>
<script type='text/x-handlebars' data-template-name='template3'>
...
</script>
<body>
However, I am using requirejs to keep my project modular and I want to be able to load the template through a .js file
I've checked out the Handlebars.compile(source) call, but it doesn't actually get the template registered with a name, for emberjs code, to be able to access. Also, please share some insights on keeping emberjs projects modular.
Before I answer - if this is a new Ember project, please use Ember App Kit or the new ember-cli.
We're using something like this for template loading:
define({
requireTemplate: function (url, name) {
$.ajax({url: url,
async: false,
success: function(templateText) {
var compiledTemplate = Ember.Handlebars.compile(templateText);
Ember.TEMPLATES[name] = compiledTemplate;
}
});
}
})
and using this we iterate over all the templates (which can be serialised from a directory).
As for keeping the project modular - again, please use either Ember App Kit or ember-cli.

Categories