How to differentiate component in angular 6 - angular5

I am trying to create a global component but that is working same like in all places..i want to use with different label values and in many palaces like aglobal component.I am learning angular 6 so facing trouble now. How do it to resolve?
service:
addComp(Names,c){
let item = {name: Names, componentid: c};
if (this.item.find((test) => test.name === Names) === undefined) {
this.item.push(item);
}
}

You can use the #Input decorator to declare values in your BreadcrumbDemoComponent that you want to be different, and pass those values as properties in the selector tag.
Example:
app-component.html
<breadcrumb-demo [label]="'Value 1'"></breadcrumb-demo>
<breadcrumb-demo [label]="'Value 2'"></breadcrumb-demo>
breadcrumb-demo.component.ts
...
export class BreadcrumbDemoComponent {
#Input() label;
...
}
breadcrumb-demo.component.html
...
<h1>{{ label }}</h1>
...

Related

Vue class components dynamically add component depending on answer from backend

So from the backend I get a array of objects that look kind of like this
ItemsToAdd
{
Page: MemberPage
Feature: Search
Text: "Something to explain said feature"
}
So i match these values to enums in the frontend and then on for example the memberpage i do this check
private get itemsForPageFeatures(): ItemsToAdd[] {
return this.items.filter(
(f) =>
f.page== Pages.MemberPage &&
f.feature != null
);
}
What we get from the backend will change a lot over time and is only the same for weeks at most. So I would like to avoid to have to add the components in the template as it will become dead code fast and will become a huge thing to have to just go around and delete dead code. So preferably i would like to add it using a function and then for example for the search feature i would have a ref on the parent like
<SearchBox :ref="Features.Search" />
and in code just add elements where the ItemsToAdd objects Feature property match the ref
is this possible in Vue? things like appendChild and so on doesn't work in Vue but that is the closest thing i can think of to kind of what I want. This function would basically just loop through the itemsForPageFeatures and add the features belonging to the page it is run on.
For another example how the template looks
<template>
<div class="container-fluid mt-3">
<div
class="d-flex flex-row justify-content-between flex-wrap align-items-center"
>
<div class="d-align-self-end">
<SearchBox :ref="Features.Search" />
</div>
</div>
<MessagesFilter
:ref="Features.MessagesFilter"
/>
<DataChart
:ref="Features.DataChart"
/>
So say we got an answer from backend where it contains an object that has a feature property DataChart and another one with Search so now i would want components to be added under the DataChart component and the SearchBox component but not the messagesFilter one as we didnt get that from the backend. But then next week we change in backend so we no longer want to display the Search feature component under searchbox. so we only get the object with DataChart so then it should only render the DataChart one. So the solution would have to work without having to make changes to the frontend everytime we change what we want to display as the backend will only be database configs that dont require releases.
Closest i can come up with is this function that does not work for Vue as appendChild doesnt work there but to help with kind of what i imagine. So the component to be generated is known and will always be the same type of component. It is where it is to be placed that is the dynamic part.
private showTextBoxes() {
this.itemsForPageFeatures.forEach((element) => {
let el = this.$createElement(NewMinorFeatureTextBox, {
props: {
item: element,
},
});
var ref = `${element.feature}`
this.$refs.ref.appendChild(el);
});
}
You can use dynamic components for it. use it like this:
<component v-for="item in itemsForPageFeatures" :is="getComponent(item.Feature)" :key="item.Feature"/>
also inside your script:
export default {
data() {
return {
items: [
{
Page: "MemberPage",
Feature: "Search",
Text: "Something to explain said feature"
}
]
};
},
computed: {
itemsForPageFeatures() {
return this.items.filter(
f =>
f.Page === "MemberPage" &&
f.Feature != null
);
}
},
methods: {
getComponent(feature) {
switch (feature) {
case "Search":
return "search-box";
default:
return "";
}
}
}
};

Spartacus 4.2 - Type '"before"' is not assignable to type 'OutletPosition'

While trying to customize the navigation slot, we are getting the error
Type '"before"' is not assignable to type 'OutletPosition'.
This is the code we are trying.
Also have tried
[cxOutletPos]=“outletPosition.BEFORE”
Documentation referred for Spartacus 4.2 :
https://sap.github.io/spartacus-docs/outlets/#template-driven-outlets
Result should be something like custom info, followed by navigation bar as shown below:
Also, as the above method didn't work I tried retrieving data through let-model for manipulation.
Array I want to retrieve data from into our component: CategoryNavigationComponent.
But using let-model and Printing model object I can see only "uid" , "typeCode" and "flexType" but not the navigatioNode and Children.
Is there any way to retrieve Navigation bar or Children array data on the screen?
****in TS File:****
settingsSubmenu: any = [];
constructor(public component: CmsComponentData<any> )
{
this.component.data$.forEach(element => {
element.navigationNode.children.forEach(child => {
this.settingsSubmenu.push(child)
});
});
}
**in HTML File**
<ng-container *ngFor="let menuItem of settingsSubmenu">
<a mat-menu-item >{{menuItem.title}}</a>
</ng-container>
If your questions is about Typescript error, then possible two solutions:
Modify tsconfig.json to ignore Typescript error:
{
...
"angularCompilerOptions": {
...
"strictTemplates": false
}
}
Modify your code to compile without errors:
In *.component.ts file add import:
import {OutletPosition} from '#spartacus/storefront';
and define variable:
outletPosition = OutletPosition;
In *.component.html file:
[cxOutletPos]="outletPosition.BEFORE"

How to use js data in a template?

I'm trying to learn some useful skills while creating my Resume Website, so I decided to try Vue.js. I had no trouble understanding the basic structure of the framework, but I have trouble actually manipulating data in .Vue files.
What I'm trying to do currently is creating two classes in a tag:
Skills
Categories (list of skills with a name)
<script>
class Category {
name = "";
skills = [];
constructor(name) {
this.name = name;
this.skills = [];
}
}
class Skill {
constructor(name, level) {
this.name = name;
this.level = level;
}
}
let programmation = new Category("Programmation");
let cpp = new Skill("C++", "Confirmed");
programmation.skills.push(cpp);
let categories = [].push(programmation, ...);
Then, I create a list of categories with skills in them (I showed only one in the example code for clarity), and try to display those in my template as such:
<template>
<div class="skills">
<h1 v-for="cat in categories" v-bind:key="cat.name">{{cat.name}}</h1>
<container xl="1200"></container>
</div>
</template>
For now, I'm only trying to display the names of my categories.
However, the compiler show me this error:
error: 'categories' is assigned a value but never used (no-unused-vars) at src\views\Skills.vue:72:5:
71 |
> 72 | let categories = [].push(programmation, ...);
| ^
73 |
74 | export default {
75 | name: "skills",
while I'm using this value in the template. How am I supposed to define and use Js variables in my template?
You are using categories as reactive property inside vue component, but you need to register to make it reactivity
Here is the fix in export:
export default {
name: "skills",
data() {
return {
categories: categories,
};
},
components: {
//Skill
}
};
Here is the sample codepen: https://codepen.io/chansv/pen/YzzGOMz?editors=1010

Set a variable inside a v-for loop on Vue JS

I have a v-for loop with vue.js on a SPA and I wonder if it's posible to set a variable at the beginning and then just print it everytime you need it, because right now i'm calling a method everytime i need to print the variable.
This is the JSON data.
{
"likes": ["famiglia", "ridere", "caffè", "cioccolato", "tres leches", "ballare", "cinema"],
"dislikes":["tristezze", "abuso su animali", "ingiustizie", "bugie"]
}
Then I use it in a loop:
<template>
<div class="c-interests__item" v-for="(value, key) in interests" :key="key" :data-key="key" :data-is="getEmotion(key)" >
// NOTE: I need to use the variable like this in different places, and I find myself calling getEmotion(key) everythime, is this the way to go on Vue? or there is another way to set a var and just call it where we need it?
<div :class="['c-card__frontTopBox', 'c-card__frontTopBox--' + getEmotion(key)]" ...
<svgicon :icon="getEmotion(key) ...
</div>
</template>
<script>
import interests from '../assets/json/interests.json'
... More imports
let emotion = ''
export default {
name: 'CInfographicsInterests',
components: {
JSubtitle, svgicon
},
data () {
return {
interests,
emotion
}
},
methods: {
getEmotion (key) {
let emotion = (key === 0) ? 'happy' : 'sad'
return emotion
}
}
}
</script>
// Not relevanty to the question
<style lang='scss'>
.c-interests{...}
</style>
I tried adding a prop like :testy="getEmotion(key)" and then { testy } with no luck...
I tried printing { emotion } directly and it doesn't work
So, there is anyway to acomplish this or should i stick calling the method every time?
Thanks in advance for any help.
It's not a good idea to use methods inside a template for non-user-directed actions (like onClicks). It's especially bad, when it comes to performance, inside loops.
Instead of using a method, you can use a computed variable to store the state like so
computed: {
emotions() {
return this.interests.map((index, key) => key === 0 ? 'happy' : 'sad');
}
}
This will create an array that will return the data you need, so you can use
<div class="c-interests__item"
v-for="(value, key) in interests"
:key="key" />`
which will reduce the amount of times the item gets re-drawn.

access object with dynamic variable vue.js

This is my object
var users ={
twitter : {
name : //,
lastname : //
},
facebook : {
name : //,
lastname : //
}
}
}
I have a dynamic variable activeuser that updates from Facebook to twitter.
What i'm trying to do is refer to the inner object in users depending on the value of activeuser. I need to give my div something like this class :
<div class=' {{users.activeuser}}'></div>
I know this is not how it should be done with vue.js. Do you have any suggestions?
Thank You!
Using VueJS you should be able to assign your dynamic variable to a Vue Model when you load the new object using a Vue setter $set('property name', 'value')
Example AJAX retreival:
$.getJSON('myURL.html?query=xxx', function(data, textStatus, jqXHR){
try{
MyVue.$set('dynamicObject', data);
}
catch(e){}
});
A generic Vue may look like this:
var MyVue = new Vue({
el:'#exampleDiv',
data: {
dynamicObject : ''
}
});
Bound to an example HTML element:
<div id="exampleDiv">
<label class="{{dynamicObject.activeuser}}">{{dynamicObject.username}}</label>
</div>
In the case that you have an object with an array of objects which also contain properties Vue makes it very simple to create many HTML elements (for each child object) by simply adding a v-repeat (example) to the desired HTML and assigning the datasource:
<div id="exampleDiv">
<label v-repeat="dynamicObject" class="{{dynamicObject.activeuser}}"></label>
</div>