Wrong breadcrumb rendered in sveltekit - sveltekit

What I want
is to have a Breadcrumb component rendered in the __layout.svelte and using a writable store $breadcrumb to read the data to display. The $breadcrumb data is filled in every route.svelte file with data provided by a loader
The problem
When the page is served (yarn dev) or rendered (yarn build with adapter-static) the breadcrumb has the data from another route and then gets updated when the page is rehydrated. Basically, it looks like the Breadcrumb.svelte component is rendered before the data is loaded in the view hence using the old store value from the previous page.
Rendering the Breadcrumb component from every single route fixes the issue but I would like to keep it in the __layout file.
Any idea on what to do ?
The code
__layout.svelte
<script>
import Breadcrumb from '../components/Breadcrumb.svelte'
</script>
<div class="wrap">
<MainMenu />
<div class="container">
<Breadcrumb />
<slot />
</div>
...
store.js
import { writable } from 'svelte/store';
export const breadcrumb = writable({});
components/Breadcrumb.svelte
<script>
import { breadcrumb } from '$lib/store';
</script>
{#if Object.keys($breadcrumb).length}
<ul class="breadcrumb noprn">
<li>Accueil</li>
{#each Object.entries($breadcrumb) as [label, url] (label)}
<li>
{#if url}
<a href={url}>{label}</a>
{:else}
<h1>{label}</h1>
{/if}
</li>
{/each}
</ul>
{/if}
routes/product/[id].svelte
<script>
export let reference; // << the data comes in here
let product = reference.product;
import { breadcrumb } from '$lib/store';
$breadcrumb = {
Catalogue: '/catalogue',
[reference.category.name]: `/catalogue/${reference.category.slug}`,
[reference.brand.name]: `/catalogue/brands/${reference.brand.id}`,
[product.name]: null
}
</script>
...

Related

I want to display animated text using <ScrollAnimation> but i see a blank page

I already installed react-animate-on-scroll and animate.css i also tried Rotate component. I want to render animated text in col-3 how can achive this
import React , { Component } from 'react';
import ReactDOM from 'react-dom';
import ScrollAnimation from 'react-animate-on-scroll';
const Animation = () => (
<ScrollAnimation animateBounce="bounceIn">
<p>Text bounces in on scroll</p>
</ScrollAnimation>
)
ReactDOM.render( <Animation />, document.getElementById("col-3"));
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<body>
<div class="row">
<div class="col-1">
</div>
<div class="col-2">
</div>
<div id="col-3">
</div>
</div>
</body>
</html>
<ScrollAnimation animateIn="rotateIn" offset={800}>
<h1>Rotating!</h1>
</ScrollAnimation>
offset is optional, it just doesn't animate if you open the page and the animation element is not below the offset from the bottom of the page (which is 150 pixels by default).
You can see the full version on https://codesandbox.io/s/optimistic-hugle-h2fh5?file=/src/Animation.js

How to use useRef to toggle between images

Given an image gallery, where the user can click an image and the selected image will be shown in the gallery below it, how can I use useRef to replace the image in the gallery div with the selected image on click? The idea is that the images will be populating the gallery at the top from an array, so each image will presumably have the useRef applied to it?
HTML
<div class="wrapper">
<div class="row">
<div class="column">
<img src="imageurl" alt="water" style="width:100%" onclick="myFunction(this);">
</div>
<div class="column">
<img src="imageurl2" alt="tree" style="width:100%" onclick="myFunction(this);">
</div>
<div class="column">
<img src="imageurl3" alt="snow" style="width:100%" onClick="myFunction(this);">
</div>
<div class="column">
<img src="imageurl4" alt="mountain" style="width:100%" onclick="myFunction(this);">
</div>
<div class="column">
<img src="imageurl5" alt="tree2" style="width:100%" onclick="myFunction(this);">
</div>
</div>
<div class="container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span>
<img id="expandedImg" style="width:100%">
<div id="imgtext"></div>
</div>
</div>
Function to toggle large image visibility
const myFunction = imgs => {
const imageRef = useRef();
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
expandImg.src = imgs.src;
imgText.innerHTML = imgs.alt;
expandImg.parentElement.style.display = "block";
}
The current state can be seen here: jsFiddle
As the React Docs state: Don’t Overuse Refs
Your code snippet is not what refs should be used for. In React, you should make things interactive via state changes, not by fiddling with the DOM, React is designed to do that for you.
However from that jsfiddle, it looks like you aren't even using React? I am unsure why you are using useRef at all?
UPDATE: Code fix
By using function to define your function (instead of an arrow function), it gets hoisted so your HTML elements can pick it up, and the getElementById method gets you the element reference you need.
Just replace all your js with:
var expandImg = document.getElementById("expandedImg");
var imgText = document.getElementById("imgtext");
function myFunction(imgs) {
expandImg.src = imgs.src;
imgText.innerHTML = imgs.alt;
expandImg.parentElement.style.display = "block";
}
...and your jsfiddle works.

Vue.js how to import SVG logo

I'm new to vue.js and am used to React. I'm currently trying to import an SVG logo into my header component but I'm not sure how. In react, I would simply do import Logo from './path; and use Logo wherever I needed it within the current component. This is basically what I'm attempting to do right now but I keep getting errors. Could anyone tell me how this could be done in Vue.js?
<template>
<header class="nav">
<img src={Logo} alt="24G Logo">
</header>
</template>
<script>
import Logo from '../assets/76_logo.svg';
export default {
name: 'Header'
}
</script>
<style lang="scss" scoped>
</style>
Here are three options. The best in my opinion is the third:
Simply input src like in any webpage <img src='../path/to/file.svg' ... though that come with some drawbacks (regardless if it's :src='logoPath' where logoPath is variable containing the same. For a short overview see this stack answer, and for more details see this article from css tricks.
Check out svg-vue-loader. Vue won't automatically import svg without a loader.
Just paste it in! (Open the svg file and copy paste it into the template.) The best option in my opinion, especially when prototyping or for smaller projects. Like so:
<template>
<header class="nav">
<svg ....
</header>
</template>
If that would make it too crowded later on, just make a new component, call it say Logo, and paste svg in there and then import MainLogo component into your header.
No need for svg-loaders. Though loaders are a dev dependency, so not like it would cost you anyway; they would just do the same thing you can do manually.
// in MainLogo.vue
<template>
<svg ....
</template>
// in MainHeader.vue
<template>
<header class="nav">
<MainLogo>
</header>
</template>
<script>
import MainLogo from '../path/to/file.vue'
export default {
components: { MainLogo }
}
</script>
Cheers
After searching and searching, and seeing all the answers were old, I went ahead and tried the newish v-html prop.
The result, success!
<div v-html="avatar" style="width: 100%"></div>
The avatar is a full element that I stored in the database.
No loaders, no imports, just using the built in resources of Vue.js
If you leave out the style, then the svg will not show.
Also, loading the full element enables me to attach a ref prop to the element. Enabling me to access the svg through script.
Hope that helps someone!!
I used this with avataaar's random avatar generator and stored the resulting svg to the database (mongo)
Here is another approach that I used:
<template>
<a href="#"
class="log-link-css-class">
<!-- SVG Icon Start-->
<img alt="alt message" class="your-logo-css-class"
src="#/assets/images/logofilename.svg">
<!-- <SVG Icon End /> -->
</a>
</template>
No import required. Vue automatically converts it to the unique URL.
edit your code
<script>
import Logo from '../assets/76_logo.svg';
export default {
name: 'Header',
data(){
Logo: Logo
}
}

Issue with lightning carousel

I am facing some issues with a lightning carousel that I am building in lwc like it is showing only 5 to 6 images inside the carousel and remaining are not showing up. If there is any limitation for the number of images could you please suggest the best approach or alternatives like HTML slideshow or any other way to build a carousel for 1000's of images inside the carousel.
Here I am loading the images from the parent component.
import { LightningElement, api } from "lwc";
export default class fcxmCarousel extends LightningElement {
#api selectdImage;
#api value;
}
<template>
<div class="slds-m-around_medium">
<div class="container">
<lightning-carousel>
<template for:each={value} for:item="rows">
<lightning-carousel-image width="100%" height="50%" key={imageURL} src = {rows.imageURL}
header={rows.imageName}
description={rows.imageDescription}>
</lightning-carousel-image>
</template>
</lightning-carousel>
</div>
</div>
<!-- </lightning-card> -->
</template>
Yes, we can only show 5-6 images using standard lightning-carousel component, for more details reefer this link https://developer.salesforce.com/docs/component-library/bundle/lightning:carousel

components load before call angularjs

I am working on angular js components there are two components that will called when their respective button is clicked
Issue: when the page loads both components are initialized , but in real they should be initialized when I click on the respective component
example:
index.html
<div class='breadcrumbs'>
<div class='inner'>
<ul class='cf' style=" margin-top: 0px;">
<li ng-click="WizardsViewerCtrl.createFirst()">
</li>
<li ng-click="WizardsViewerCtrl.createSecond()">
<span>Arrange Questions</span> </a>
</li>
</ul>
</div>
</div>
<div ng-show="viewFirstRoute">
<first-component></first-component>
</div>
<div ng-show="viewSecondRoute">
<second-component></second-component>
</div>
index.js
$scope.viewFirstRoute=false;
$scope.viewSecondRoute=false;
function createFirst() {
$scope.viewFirstRoute=true;
$scope.viewSecondRoute=false;
}
function createSecond() {
$scope.viewFirstRoute=false;
$scope.viewSecondRoute=true;
}
problem is when this page index.html is loaded ,both components are initialized
first.component.js
angular
.module('AOTC')
.component('firstComponent', {
templateUrl: 'first.html',
controllerAs: 'firstCtrl',
controller:(function ($scope) {
console.log("first component loaded");//it prints while index.html is loaded even i didn't clicked on this component
})});
second.component.js
angular
.module('AOTC')
.component('secondComponent', {
templateUrl: 'second.html',
controllerAs: 'secondCtrl',
controller:(function ($scope) {
console.log("second component loaded");//it prints while index.html is loaded even i didn't clicked on second component
})});
summarizing: two components on same route must be initialized when I click on the respective component , but behavior noticed components are loaded as soon as route is loaded it doesn't care about the click, see comments in the JS file
Use ng-if instead of ng-show. it should fix the issue.
<div ng-if="viewFirstRoute">
<first-component></first-component>
</div>
<div ng-if="viewSecondRoute">
<second-component></second-component>
</div>
ng-show: it will add component to DOM but set its display property to none.
ng-if: Will add or remove component from DOM conditionally.

Resources