NuxtJS add external script component not working - javascript

I'm trying to embed a script from an external JS, according to the documentation and this post (Include external javascript file in a nuxt.js page) I have something like the following...
<template>
<div>
<blocksurvey-widget>
some details
</blocksurvey-widget>
</div>
</template>
export default {
head: {
script: [
{
type: "module",
src: "https://blocksurvey.io/assets/js/blocksurvey-widget.js",
},
],
},
}
I am wondering why this is not working and throws the [Vue-warn] error:
Unknown custom element: <blocksurvey-widget> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
I believe the script is appended to the head, and I think I need to register the component, but I had the impression this would be working normally once the script has been added. Do I have find some way to add the <blocksurvey-widget> component?

Related

How can I add a script function to React

I am trying to add an external application Chameleon onto my react application and for that I have to add the javascript function to my application.
I only want it to be called in specific situations so I don't want to load it in my index.html. I tried adding it to the render function of my component as:
render() {
return(
<div>
<head>
<script type="text/javascript">/* Chameleon - better user onboarding */!function(t,n,o){var a="chmln",c="setup identify alias track clear set show on off custom help _data".split(" ");n[a]||(n[a]={}),n[a].accountToken=o,n[a].location=n.location.href.toString();for(var e=0;e<c.length;e++)!function(){var t=n[a][c[e]+"_a"]=[];n[a][c[e]]=function(){t.push(arguments)}}();var s=t.createElement("script");s.src="https://fast.trychameleon.com/messo/"+o+"/messo.min.js",s.async=!0,t.head.appendChild(s)}(document,window,"TOKEN");
chmln.identify(USER.ID_IN_DB, { // Unique ID of each user in your database (e.g. 23443 or "590b80e5f433ea81b96c9bf6")
email: USER.EMAIL });
</script>
...
...
</head>
</div>
)
}
But the above doesn't seem to work. I tried the same inside a helmet but no luck. Both of them show an error for
SyntaxError: Unexpected token
Is there a way I can load this function in a specific component or do I have to do it in the index.html?
You seem to have a strong misunderstanding of what react is for and how it is used.
1) There should only ever be 1 head element on the page, and it should be in index.html not in the rendered output of a component.
2) Having a component render a <script> tag goes against the point of using react.
What you need to do is import the code you need into your component:
import './path/to/file.js'
And then from there chmln should be available on the window object
window.chmln.identify()

Using custom components as router-link tag in Vue

I'm trying to make the following Vue component work:
<template>
<div>
<cx-button href="/new">
Create
</cx-button>
<router-link tag="cx-button" to="/new" class="cx-raised">Create</router-link>
</div>
</template>
<script>
import cxButton from '../elements/cxButton/cxButton';
export default {
// ...
components: {
cxButton
}
}
</script>
But it throws: [Vue warn]: Unknown custom element: <cx-button> - did you register the component correctly? For recursive components, make sure to provide the "name" option. found in ---> <RouterLink>.
Name of the button element is provided.
cx-button component is rendered fine by itself, same for router-link without using cx-button as value in tag property. The question is: what should I do to make router-link use custom elements, such as my button, as its tag?

Vue.js 2.0: Apply vue component rendered using v-html, compile the markup

I'm using VueJS 2.0
Is there any way to make the below render as a link?
Here is my vue component:
<template>
<div v-html="markup"></div>
</template>
<script>
new Vue({
data() {
return {
markup: '<router-link :to="{path: 'https://www.google.com'}"></router-link>',
});
},
});
</script>
In the above example, I want to dynamically export a piece of markup, it contains some dynamic contents, such as router-link like above.
But that content did not compile, and exports a <router-link> tag as a final result.
Any way to make it compile programmatically?
What I really want is to find a way to compile a piece of html manually. If v-html doesn`t work, Is there any other way?
v-html works only for pre-compiled html which is basically generated text.
If you want do dynamically change content, simply use if conditions to render your list view based on prop that will tell you the type of the list view.
I don't think it's a good idea to save the markup in your db. It's rather more convenient to save some settings in your db and based on those to render the necessary html. (the prop type in your case). Maybe if you provide a more concrete example, some suggestions will follow. As you can see, the answers were based on your router-link example which I think is not enough to answer your question
I don't think you can instantiate Vue instances via v-html directive. You must override the default to do that, which would take lots of efforts.
If you just want dynamic links, why not try this:
data: {
menu: []
}
and then :
<router-link v-for="item in menu" :to="item.src">{{item.name}}</router-link>
PS: Can you give an example that you must do such things? I am really interesting in what needs it would be.
Given that you want to render a list of links, one way to do this can be like this:
<template>
<router-link v-for="list in lists" :to="{path: list}"></router-link>
</template>
<script>
new Vue({
data() {
return {
lists: ['https://www.google.com', 'https://www.stackoverflow.com']
});
},
});
</script>
Edit:
You can use an approach like following as well using with the help of dynamic components.
Vue.use(VueRouter)
new Vue({
el: "#app",
data: {
dynamicComp: "router-link"
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.2.0/vue-router.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="app">
somethind
<component :is="dynamicComp" :to="{path: 'https://www.google.com'}"></component>
</div>

Two different layouts in aurelia app

I'd like to use two separate layouts for my aurelia app. Difference between them is that one doesn't have a sidebar. Currently I'm using one layout file defined as below:
<template>
<div class="container">
<router-view></router-view>
</div>
</template>
If an active route needs this sidebar to appear I'm just putting it into its view.
What I'd like to achieve is to add another layout that would have this sidebar by default:
<template>
<require from="../common/elements/sidemenu/sidemenu"></require>
<div class="container">
<sidemenu></sidemenu>
<router-view></router-view>
</div>
</template>
So the question is - how to do this? Is it even possible with an aurelia app to have multiple layouts (or master pages, however you call those)?
Use aurelia.setRoot()
You can manually set up your application by specifying a script with configure instructions in your index.html. Typically, this is set to main.
index.html
<body aurelia-app="main">
In this script you can specify a root view model using aurelia.setRoot('root'). If no argument is provided, the convention is to use 'app'.
main.js
aurelia.start().then(() => aurelia.setRoot());
However, you can inject the aurelia object anywhere in your application, and call the setRoot function at any time to load a different root view model.
home.js
#inject(aurelia)
export class HomeViewModel {
constructor(aurelia) {
this.aurelia = aurelia;
}
doStuff() {
this.aurelia.setRoot('withSidebar');
}
}
One common use case for this is having a login page, and I've created a complete template for this use case that you can review, clone, or fork here: http://davismj.me/portfolio/sentry/

Iron Router: Load js script after template has been rendered

I'm trying to load a javascript file (using IRLibloader) after the Iron Router has rendered the template:
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
});
Router.route('/', {
name: 'landing',
template: 'landing',
onBeforeAction: function () {
var googleAPI = IRLibLoader.load('http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false');
var fancyInput = IRLibLoader.load('/js/fancyInput.js');
var geoComplete;
if(googleAPI.ready()){
geoComplete = IRLibLoader.load('/js/jquery.geocomplete.min.js');
}
if(googleAPI.ready() &&
fancyInput.ready() &&
geoComplete.ready()){
console.log('All ready');
this.next(); // Render the page when all the libraries are ready
// Testing this here
if(Meteor.isClient){
console.log("Meteor.isClient");
IRLibLoader.load('/js/landing.js');
// Set places autocomplete
Template.landing.rendered = function(){
$('section :input').val('').fancyInput()[0].focus();
$('section :input').geocomplete();
console.log("loading.js ejecutandose (after render)");
}
}
}
}
});
But when I browse localhost:3000, the layout gets rendered, the googleAPI, fancyInput and geocomplete libraries are loaded too since the 'all ready' message gets printed at console, and landing.js also gets loaded (since it loads the background image and the message 'Meteor.isClient' also gets printed).
But then, the 'landing' template never gets rendered. Its content does not appear, and the console message inside the Template.landing.rendered never gets printed. This is the template.js file:
<template name="landing">
<img id='logo' src="img/logos/logo.png">
<div id='content'>
<section class='input'>
<div>
<input type='text' placeholder='Type text here'>
</div>
</section>
</div>
</template>
I also tried loading landing.js with onAfterAction, which seems to happen before the onBeforeAction according to the Firebug console. How strange!
I can't understand why the template is not being loaded, since no error appears at meteor console. Any idea?
EDIT: it does work if I remove the layout, which looks like this:
<template name="layout">
<head>
<title>Welcome to my app</title>
</head>
</template>
What's wrong with this layout?
So, I think you might be overthinking this a little. Why not use existing packages for these libraries? Aside from being significantly easier to use, some of that 3rd party code would get minified into the main app js file instead of making additional HTTP requests to download them.
For example, dburles:google-maps gets you the Google Maps API and extra libs of your choice (with the option to only load on specific routes) and jeremy:geocomplete gets you Geocomplete (which automatically installs that maps package as a dependency). See the jeremy:geocomplete README for implementation.
As for Fancy Input, why not create a simple Meteor package wrapper for that so you can just meteor add fancy-input?
Also, your Template.landing.rendered callback should not be in an onBeforeAction. Ideally, it should be in its own file with other code for the landing template.

Categories

Resources