outros$1 undefined errors with svelte web components (custom elements) - web-component

when building web components, aka named custom elements, with svelte 3.19.2, i am getting outros$1 undefined error just before outros$1.c.push when i try and use {#if} or {#await} but {#each} is working fine.
Works:
{ #each myTodos as todo }
<li>{ todo.text }</li>
{ /each }
Doesn't Work:
{ #if loadingTodos }
<p>loading</p>
{ :else }
<p>loaded</p>
{ /if }
Doesn't Work:
{ #await todos }
<p>loading</p>
{ :then result }
<p>loaded</p>
{ :catch error }
{ error }
{ /await }
Relevant Supporting Code:
const todos = query(apolloClient, { query: Q_TODOS_ALL });
todos.result().then((result) => { myTodos = result.data.getTodos; loadingTodos = false; });
Anyone have any ideas how to address this? I'm new to Svelte and at a loss. This code couldn't be simpler code. The graphql promise is returning and works with an each, if's and await's in the template both throw outros$1 undefined errors though.
Seems a couple of other bugs on github (#3448 & #3165) are also related to there being no checks around outros and it going undefined. Not sure if they are related or not. i'm wondering if this is a know issue with using svelte for building web components? Thanks.

Related

How to check for an element that may not exist using Cypress

I am writing a Cypress test to log in to a website. There are username and password fields and a Submit button. Mostly logins are straightforward, but sometimes a warning dialog appears first that has to be dismissed.
I tried this:
cy.get('#login-username').type('username');
cy.get('#login-password').type(`password{enter}`);
// Check for a possible warning dialog and dismiss it
if (cy.get('.warning')) {
cy.get('#warn-dialog-submit').click();
}
Which works fine, except that the test fails if the warning doesn't appear:
CypressError: Timed out retrying: Expected to find element: '.warning', but never found it.
Then I tried this, which fails because the warning doesn't appear fast enough, so Cypress.$ doesn't find anything:
cy.get('#login-username').type('username');
cy.get('#login-password').type(`password{enter}`);
// Check for a possible warning dialog and dismiss it
if (Cypress.$('.warning').length > 0) {
cy.get('#warn-dialog-submit').click();
}
What is the correct way to check for the existence of an element? I need something like cy.get() that doesn't complain if the element can't be found.
export function clickIfExist(element) {
cy.get('body').then((body) => {
if (body.find(element).length > 0) {
cy.get(element).click();
}
});
}
export const getEl = name => cy.get(`[data-cy="${name}"]`)
export const checkIfElementPresent = (visibleEl, text) => {
cy.document().then((doc) => {
if(doc.querySelectorAll(`[data-cy=${visibleEl}]`).length){
getEl(visibleEl).should('have.text', text)
return ;
}
getEl(visibleEl).should('not.exist')})}
I have done it with pure js.
cy.get('body').then((jqBodyWrapper) => {
if (jqBodyWrapper[0].querySelector('.pager-last a')) {
cy.get('.pager-last a').then(jqWrapper => {
// hardcoded due to similarities found on page
const splitLink = jqWrapper[0].href.split("2C");
AMOUNT_OF_PAGES_TO_BE_RETRIEVED = Number(splitLink[splitLink.length - 1]) + 1;
})
} else {
AMOUNT_OF_PAGES_TO_BE_RETRIEVED = 1;
}
});
I'm trying to check if element exists on body
cy.get('body').then((jqBodyWrapper) => {
With a pure js querySelector
if (jqBodyWrapper[0].querySelector('.pager-last a')) {
Then I fire my cy.get
cy.get('.pager-last a').then(jqWrapper => {
The hasClass() or for CSS selector has() is an inbuilt method in jQuery which checks whether the elements with the specified class name exists or not. You can then return a boolean to perform assertion control.
Cypress.Commands.add('isExistElement', selector => {
cy.get('body').then(($el) => {
if ($el.has(selector)) {
return true
} else {
return false
}
})
});
Then, it can be made into a special cypress method with TypeScript file (index.d.ts) file and can be in the form of a chainable.
declare namespace Cypress {
interface Chainable {
isExistElement(cssSelector: string): Cypress.Chainable<boolean>
}
}
As in the example below:
shouldSeeCreateTicketTab() {
cy.isExistElement(homePageSelector.createTicketTab).should("be.true");
}

Meteor, creating update form and filling fields

I have the following structure:
{
id: 23423-dsfsdf-32423,
name: Proj1,
services: [
{
id:sdfs-24423-sdf,
name:P1_Service1,
products:[{},{},{}]
},
{
id:sdfs-24jhh-sdf,
name:P1_Service2,
products:[{},{},{}]
},
{
id:sdfs-2jnbn3-sdf,
name:P1_Service3,
products:[{},{},{}]
}
]
},
{
id: 23423-cxcvx-32423,
name: Proj2,
services: [
{
id:sdfs-xvxcv-sdf,
name:P2_Service1,
characteristics:[{},{},{}]
},
{
id:sdfs-xvwqw-sdf,
name:P2_Service2,
characteristics:[{},{},{}]
},
{
id:sdfs-erdfd-sdf,
name:P2_Service3,
characteristics:[{},{},{}]
}
]
}
I have no problem creating a form this schema an insert form with quickForm.
But I cant figure out (and tried to read every tutorial and instruction and nothing worked) how to create an update form with all fields filled and (need to expand and fill the services and the characteristics arrays also:
of course, as i said, in update i need the services and characteristics to expend to the right size with all the fields.
But if i could understand how to fill the form fields i could understand myself how to expend the arrays...
i've tried:
{{> quickForm collection="Projects" id="updateProjectForm" collection="Projects" type="method" class="update-project-form" doc=project }}
with:
import SimpleSchema from 'simpl-schema';
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
// Attaching the subscription to the template so we can reuse it
Template.ProjectSingle.onCreated(function(){
var self = this;
self.autorun(function(){
var id = FlowRouter.getParam('id');
self.subscribe('projectSingle', id);
});
});
Template.ProjectSingle.helpers({
project: ()=> {
var id = FlowRouter.getParam('id');
console.log(Projects.findOne({_id: id}));
return Projects.findOne({_id: id});
}
});
I can't even see the console.log() printing.
This solution at list didn't crash the meteor server... everything else i've tried crashed the server on many errors
Maybe i need to mention that i'm using partials so maybe there is a problem with the JS files but i don't think so as the onCreated method is being read.
10x.
EDIT:
I've removed the partial for the update template and it is now in the root Template with its own JS with the method:
projectDoc: ()=> {
var id = FlowRouter.getParam('id');
console.log("Update: " + Projects.findOne({_id: id}));
return Projects.findOne({_id: id});
}
Now i can see this method is being called but for some reason it is being called twice. First with the correct data and then getting undefined so i've still not getting the fields showing anything but if i could find why it is being called twice i will solve the first level form (no services and so on)
Solved it (Not sure this is the best way as i'm still having two calls to the method but this is working for now:
projectDoc: ()=> {
var id = FlowRouter.getParam('id');
if(Projects.findOne({_id: id}) != null){
console.log(Projects.findOne({_id: id}));
thisProject = Projects.findOne({_id: id});
return Projects.findOne({_id: id});
} else {
return thisProject;
}
}

React front end for Wordpress API - Adding content.rendered Only secure origins are allowed

Just as a preface, I am using create-react-app boiler plate.
I am trying to parse out a post from the wordpress API into a react component so I can extract all images and make them their own JSX objects. I need to have each post have its own on click method so I cant just use the dangerouslyaddHTML function in React.
Currently, I search through the string of json that had the rendered HTML from the WP content of each post and find all img tags. I then add then image src to an array and set this in my state.
However I am getting this error :
DOMException: Only secure origins are allowed
The site I have this currently hosted on it http://natalie.madeline-omoore.com/build/
The code for part of my component is below:
`componentDidMount(){
var owner;
for(var i = 0; i < this.props.categoryId.length; i++) {
if (this.props.categoryId[i].num === this.props.content.categories[0]) {
owner = this.props.categoryId[i].category;
this.setState({
catname: owner
})
break;
}
}
var theContent = this.props.content.content.rendered;
var output = $(theContent).find("img").map(function() {
return this.src;
}).get();
this.setState({
postImages: output
});
}
click(){
this.updateActive();
this.props.fix();
}
render() {
if (this.props.className === this.state.catname) {
return (
<div >
{ this.props.className === this.state.catname &&
<article className={`${this.state.catname}`} >
{this.state.postImages.map((image, i) =>
<ImageContain key={image} image={image} fix={this.props.fix} />
)}
</article>
}
</div>
);
} else {
return null;
}
}`
I am new to react so thank you!
This sounds like an issue with the 'service worker' that is default with create-react-app
You can deregister the worker by adding the following to index.js:
import { unregister } from './registerServiceWorker';
// ...
unregister();
Be sure to call unregister() after registerServiceWorker() is called.
You can learn more about this here: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app
Good luck, and happy coding!

React rendering recursion stops without error

I've encountered a problem with rendering some elements in React.
(I use ImmutableJS)
renderComponents: function(components) {
if(components.isEmpty()) return [];
var table = [];
components.map(function(component) {
table.push(<ComponentTableElement key={ component.get('id') } data={ component } />);
if(component.has('children')) {
var children = component.get('children');
table.concat(this.renderComponents(children));
}
});
return table;
},
As I looked for error, I found that this.renderComponents(children) doesn't return anything at all and the code somehow stops.
I mean before that line everything works ok, but then after this line, when i try to console.log something, it doesn't show up. And it doesn't even reach return table.
So what is wrong with that code?
In the context of the function you pass to map, this refers to the window object, not to the current component instance, so this.renderComponents is undefined when you try to call it.
components.map(function(component) {
this === window;
});
You can pass a value to use as this in the body of your function as the second parameter of Array::map.
components.map(function(component) {
table.push(<ComponentTableElement key={ component.get('id') } data={ component } />);
if(component.has('children')) {
var children = component.get('children');
// here, `this` refers to the component instance
table.concat(this.renderComponents(children));
}
}, this);
If you're using ES6, you can also use fat-arrow functions, which are automatically bound to this.
components.map((component) => {
table.push(<ComponentTableElement key={ component.get('id') } data={ component } />);
if(component.has('children')) {
var children = component.get('children');
// here, `this` refers to the component instance
table.concat(this.renderComponents(children));
}
});

Letting a user use a compiled RequireJS Widget after it has loaded

I'm writing a JS Widget using RequireJS. After finishing the widget I'm compiling it with r.js and Almond. All goes well - but I couldn't find an easy way to let the user use the widget without using RequireJS himself - as the widget code loads async (RequireJS uses AMD).
What I'm doing now is busy waiting for the widget code to load and using it only after detecting it has loaded. This is not very user-friendly.
Is there a way to let just do something like this?
var widget = new Widget();
instead of doing busy wait like:
count = 0;
function loadWidget() {
if (typeof Widget != 'undefined') {
var p1 = new Widget();
p1.render();
} else {
if (count > 10) {
console.log('Failed to load the Widget');
return false;
}
setTimeout(loadWidget, 50);
count++;
}
}
$(document).ready(function() {
loadWidget();
});
Thanks!
EDIT:
my build.js
({
name: './lib/almond.js',
out: './deploy/sdk.min.js',
baseUrl: '.',
optimize: 'uglify2',
mainConfigFile: 'sdk.js',
include: ['sdk'],
wrap: true
})
Code on the web page (assume no other script tags on page):
<script src="mywidget.js" data-main="scripts/sdk" id="mywidget"></script>
No sure if the 'data-main' is really required as the js is compiled.
You need to follow the instructions provided with Almond. To summarize the essential points what is in the doc there, what you need in your build config the following configuration:
wrap: {
startFile: 'path/to/start.frag',
endFile: 'path/to/end.frag'
}
And the start.frag should be:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else {
root.Widget = factory();
}
}(this, function () {
and the end.frag:
return require('main');
}));
The end fragment calls require in its synchronous form, which is really synchronous in this case (and not the pseudo-synchronous sugar that can be used by RequrieJS itself).
I've tried this before. It works.

Resources