I have a component called projectDetailPage where I am passing json variable to render it's value. I have a container component called ProjectCardContainer which has anchor tag and I am opening it to projectDetailPage I am attempting to render the json date and for that I am checking it with console.log(json);. When I click on ProjectCardContainer
<h6 className="link-hidden">
<a href={`/projectdetailpage/${props.projectID}`} >
{props.projectName}
</a>
</h6>
It opens projectDetailPage and I don't see any console.log. What is going wrong here? Also is there any correct approach for rendering json in to the component? Thanks.
Gist code Link
I forgot to Add the <Route path='/ProjectDetailPage/:projectID' component={ProjectDetailPage} /> in my root component. I Added it and solves my problem.
Related
What I'm trying to do
A simple way to render the content of a markdown file when it's passed as a string to another component using .compiledContent (or even using .rawContnent)? Or even a better way than this as obviously usually in Astro we can use the <Content /> Component, but from my knowledge, I can't pass a component or this functionality to another component without using a <slot /> in the parent component.
I have some JS for the parent component and using a <slot/> instead of passing the props to the component would change things, so hopefully looking for a solution with using this.
My setup
Data stored in /src/data/experience as markdown files with a year and a description formatted as markdown in the content section of each file
A component called Tabs.astro which takes props of headings and contents which are both lists of strings
A page /src/pages/experience.astro with the Tabs component in it which is displaying this data
I take the below code to get the data from the markdown files and pass the years and descriptions to the Tab component.
experience.astro
---
import Tabs from "../components/Tabs.astro";
const jobs = await Astro.glob("../data/experience/*.md");
const years = jobs.map((job) => job.frontmatter.year);
const descriptions = jobs.map((job) => job.compiledContent);
---
<!-- My component taking the data to be rendered -->
<Tabs headings={years} contents={descriptions} />
Tabs.astro
And the component renders the info like so
<!-- Tabs -->
<div class="tabs">
<ul class="tabs-header">
{
headings.map((heading) => (
<li>{heading}</li>
))
}
</ul>
<ul class="tabs-content">
{contents.map((content) => <li class="tab">{content}</li>)}
</ul>
</div>
My current solution
At the moment using .compiledContent gets me the correct HTML, however it is all in a string so the HTML doesn't actually render.
What I'm looking for
Is there a native way in Astro to pass markdown as a prop to a component?
If not is there a manual and recommended way in Astro to convert a markdown string and sanitise it to protect against XSS attacks? (if this is a risk in Astro when rendered statically?)
If not what are your most recommended ways to render markdown and sanitise it in JS?
Thanks so much for your time and help! I'm loving using Astro
p.s Also happy to concede and just use a <slot/> in my component if needed... ;)
Astro has a set:html directive you can use in combination with a Fragment like this
<Fragment set:html={post.compiledContent()}/>
After a bit of struggling with this myself, the current solution from the Astro docs for a single file without looping is the following.
Import your file with {Content as YourAliasName} from '../yourPath/yourFileName.md'
Then just use it as a tag <YourAliasName />
Example from the docs for reference:
---
import {Content as PromoBanner} from '../components/promoBanner.md';
---
<PromoBanner />
https://docs.astro.build/en/guides/markdown-content/#the-content-component
VueJS slot could be placed anywhere inside a parent component.
However, I have a use case where I need to show a slot in another (foreign) component outside the parent component.
For example, I have component Student:
<template>
<slot name="detail" />
<slot name="status" /> <!-- I don't want to render this slot inside this component, but somewhere else -->
</template>
I want to display the student's status in a header section outside the student component as below:
<div class="Header">
<!-- student status slot should go here-->
<student-status-slot></student-status-slot>
</div>
<div class="InputForm">
<student>
<template #detail>This the detail information about student</template>
<template #status>Grade A</template>
</student>
</div>
You may suggest to create a new "student-status-slot" component. However, the idea is to have all student related information, including "status" declared under the component, but render some of the slot somewhere else.
I have tried another approach creating a separate component and pass the status data via prop. But That is not what I wanted to achieve. I don't want to pass data, but re-use the student status component, which can be dynamic.
In a parent component you can access child's slots by adding ref attribute to child, and then render the VNode obtained. See the demo here https://codesandbox.io/s/happy-einstein-9f5rke?file=/src/components/StudentPage.vue
But actually I wouldn't recommend this way such it's not conventional and slots were not designed for this. I think you should rather consider using portals (Vue 3 portals or https://www.npmjs.com/package/portal-vue if you use Vue 2) to achieve your goal
I am trying to add dynamically an id into tag
<a href="/profile?id="{this.state.userInfo.id}>
it's not working. VS code keep saying that I have to add ...
Any idea ? Sorry I am newby in JavaScript and React.
Thanks
If you try to render link like /profile?id=123, where 123 is userId, then you should use template strings to insert variable value to your string.
<a href={`/profile?id=${this.state.userInfo.id}`}>
Now expression in braces would be interpreted and transformed into string with variable value.
But, if you need to make working link with react-router, you need to use Link from react-router-dom. You can find examples here
You need to use string template literal.
<a href={`/profile?id=${this.state.userInfo.id}`}>
In react we dont user the tag for routing insted we use a package/library called react-router-dom for handling routing. You can go throught the documentaion as ther are may ways for dynamic routing in React. Hope this helps. As the tag refreshes the page a may have an unlikely behavior.
you could use <Link> instead of <a> using react-router-dom
this sample is from their website
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
</nav>
</Router>```
I am working on Vue app that incorporates Vue Bootstrap Calendar, and I would like to be able to override the content of the day cell (handled by the Day.vue component) to add my own custom content inside. My thought was initially to modify the Day component to include <slot></slot> tags and pass in the custom content that way.
The problem has to do with accessing the Day component. To include the calendar in your app, you include the Calendar.vue component, which includes Week.vue, which in turn includes Day.vue. As I understand slots, I have to have the child component (Day.vue in this case) included in the component where I'm passing the data, which means it would need to be included in my own component.
If this is not possible, my other thought is to perhaps modify the library by adding another configuration prop (something like dayCustomContent) to the Calendar.vue that indicates that the Day cell content is custom content, pass that in to Calendar.vue, and then down to Day.vue, and then in the Day.vue template, have a v-if conditional based on this prop that either displays the custom content or the default cell content, something like:
<template>
<div class="day-cell" v-if="dayCustomContent">
...my custom content here...
</div>
<div class="day-cell" v-else>
...default events from my.events goes here...
</div>
</template>
I would probably then need to define a custom component to render whatever custom content I want to display, and somehow include that component within Day.vue.
So to sum up, my questions are these:
1) Is there a way to do what I need with slots?
2) For my second option, am I going down the right path? I'm open to suggestions.
UPDATE: I was able to get this done by adding a boolean customDayContent prop in Calendar.vue like so and passing it down to Week.vue and then to Day.vue:
<template>
...
<div class="dates" ref="dates">
<Week
v-for="(week, index) in Weeks"
:firstDay="firstDay"
:key="week + index"
:week="week"
:canAddEvent="canAddEvent"
:canDeleteEvent="canDeleteEvent"
:customDayContent="customDayContent"
:displayWeekNumber="displayWeekNumber"
#eventAdded="eventAdded"
#eventDeleted="eventDeleted"
></Week>
</div>
...
</template>
<script>
export default {
...
props: {
...
customDayContent: {
type: Boolean,
default: false
}
},
}
</script>
and then in Day.vue, do like I had suggested with v-if:
<template>
<div class="day-cell" v-if="customDayContent">
<custom-day></custom-day>
</div>
<div
class="day-cell"
:class="{'today' : day.isToday, 'current-month' : day.isCurrentMonth, 'weekend': day.isWeekEnd, 'selected-day':isDaySelected}"
#click="showDayOptions"
v-else
>
... existing code goes here...
</div>
</template>
The last part is referencing the CustomDay.vue component referenced in my v-if block. I want the user to be able to define the content of their own custom CustomDay.vue template in their own parent app. However, I'm having trouble trying to figure out how to do that. Following the pattern of including components already in this component, I added this in the components section of Day.vue:
CustomDay: require("../../../../src/Components/CustomDay.vue").default
? require("../../../../src/Components/CustomDay.vue").default
: require("../../../../src/Components/CustomDay.vue")
However, no matter what I try along these lines, I get an error that the relative module was not found. On top of that, I need to add it to the componentsarray only if customDayContent is true. What is the best way to do that? In a watcher or computer property, perhaps? Or another way?
I'm trying to display loading screen inside router outlet till data is received.
here is my code inside index.html
<root>
<div class="app-content text-center">
<div class="app-content-body" >
<div class="loader_div" >
<div class="loader"></div>
</div>
</div>
</div>
</root>
which works as expected but as I try to execute same code inside It remains Inside the screen even after the screen Is loaded.
One possible solution is that I can subscribe in router event and use instanceof NavigationStart and NavigationEnd.and use ngIf to remove the DOM from routeroutlet.
Is there any other easier way to solve that?
Edit1: After subscribing in router event I realized it wasn't wise decision. Because in case more than one nested router-outlet It'll show refresh screen in whole page instead of the part where the child router-outlet is located.
When I inspect DOM, <ng-component> doesn't replace <router-outlet> instead it's loaded after finishing tag.(</router-outlet>)
Is it a bug of Angular2?