How do I use ember-crumbly for non-nested routes? - javascript

I'm trying add breadcrumbs to this application using ember-crumbly.
I couldn't find the git repo, so to see the code, you'll have to clone the full application by clicking the button "Download git repository" in Course Material and then go to the branch step-14 by running the following command after going into the repo via command line:
git checkout step-14
I'm adding breadcrumbs by making the following changes to the files:
app/routes/album.js
import Ember from 'ember';
export default Ember.Route.extend({
breadCrumb: {
title: 'Album'
}
});
app/routes/index.js
import Ember from 'ember';
export default Ember.Route.extend({
breadCrumb: {
title: 'Home'
},
model() {
return this.store.findAll('album');
}
});
app/templates/application.hbs
<header>
<h1>BümBöx</h1>
</header>
<div class="breadcrumb">
{{bread-crumbs tagName="ul" outputStyle="foundation"}}
</div>
{{outlet}}
{{now-playing}}
I'm hoping when I go to http://localhost:4200/album/1, it would look like this:
but instead, it looks like this:
I'm guessing it's because my routes are not nested in directories (as in it's not app/routes/home/album.js), which isn't compatible with the demo from ember-crumbly. Can someone help me figure out how to add ember-crumbly to this application? Much appreciate.

Related

Vuejs: shared components used on multiple pages disappeared

right now, I'm writing a single-page-application in vue.js using vue-router. Pages like the homepage, sign-in page etc. all share a navigation and footer component. On a few pages however, I need the entire screen so that the navigation and footer shall not be displayed.
Hence, I decided to nest components and include the navigation and footer component when necessary. My problems now is, that the navigation and footer template disappeared on all pages.
Edit: A more complete demo can be found in this Github repository.
Here's a simplified version of the files I'm using:
index.html:
<div id="app">
<router-view></routerview>
</div>
router.js:
import Homepage from './homepage.vue';
import SignIn from './signin.vue';
const router = new VueRouter({
routes: [
{path: '/', component: Homepage},
{path: '/signin', component: SignIn},
]
})
homepage.vue and signin.vue components:
<template>
<navigation></navigation>
// some page-specific content
<footer-vue></footer-vue>
</template>
<script>
import Navigation from './navigation.vue';
import Footer from './footer.vue';
export default {
components: {
'navigation': Navigation,
'footer-vue': Footer,
},
}
</script>
A component without navigation and footer:
<template>
// some page-specific content
</template>
Is it even possible to nest components this way? I hope someone is able to point me into the right direction.
Both homepage.vue and signin.vue have invalid templates. e.g.
<template>
<navigation></navigation>
<h1>The homepage</h1>
<footer-vue></footer-vue>
</template>
This is not allowed as it has 3 root nodes. See https://v2.vuejs.org/v2/guide/components.html#A-Single-Root-Element
You need to wrap it to get it to work:
<template>
<div>
<navigation></navigation>
<h1>The homepage</h1>
<footer-vue></footer-vue>
</div>
</template>
Note that this limitation does not apply to functional components and is also expected to be lifted for all components in Vue 3.
Much more worrying is that you're not seeing any errors messages for this. You really need to look into that as it suggests there's something very much amiss with your development setup.
An example of the error message you should be seeing:
new Vue({
el: '#app',
template: '<div></div><div></div>'
})
<script src="https://unpkg.com/vue#2.6.10/dist/vue.js"></script>
<div id="app">
</div>

NuxtJs vue-flip not flipping between front and back sides

I do install vue-flip into a NuxtJs (VueJS) project created using this command: npx create-nuxt-app <project-name>.
In the index.vue file i just add:
<vue-flip active-click="true">
<div slot="front">
front
</div>
<div slot="back">
back
</div>
</vue-flip>
I do register the plugin at nuxt.config.js :
plugins: [
'~/plugins/vue-flip'
]
And create the file vue-flip.js at the plugins folder :
import Vue from 'vue'
import VueFlip from 'vue-flip'
Vue.use(VueFlip)
After run npm run dev and at localhost:3000 the text front and back are visible instead of showing just the front text so when clicking the back text would appear.
How can i fix?
Did you checked you console for errors? Because there should be ones..
According to docs https://www.npmjs.com/package/vue-flip is not a vue plugin but a component, so it wont work like this. You need to specify it as a component where you use it.
import VueFlip from 'vue-flip';
export default {
components: {
'vue-flip': VueFlip
}
}

Using a component containing other components within a router-view in Vue.js

I am trying to build a layout using single-file components in Vue.js, with dynamic population and URLs using Vue-router. (I'm using the webpack template via vue-cli as well.)
It works as expected for my app.vue file-- containing the nav, sidebar, page head, and <router-view>-- and the <router-view> content appeared as expected when the correct <router-link> is clicked... until I tried to add subcomponents to the add-load component being called to the <router-view>. Now, nothing appears at all, despite not throwing any errors.
Admittedly, I am not basing my structure on any examples, as I couldn't really find any doing it the way I was hoping to. I wanted to use nested components by calling them like custom elements-- I think this makes the code much easier to read and maintain. I'm not entirely sure how to structure it otherwise, to be honest. Using multiple <router-view>s as siblings to each other seems counterintuitive to me.
I've tried a variety of combinations of how and where to import and call the components, and nothing has worked. The only way I can get any content to load is if I only call a single component for path: '/add-load'. Is it just impossible to use multiple components outside of your base app.vue? I find that hard to believe. Here's what I started with.
From my index.js:
import AddLoad from '#/components/AddLoad'
import AddLoad from '#/components/ProgressSteps'
import Stops from '#/components/Stops'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
components: {
Sidebar,
TopNav,
MobNav,
PageHead
}
},
{
path: '/add-load',
components: {
AddLoad,
ProgressSteps}
}
]
})
From my App.vue file (the multiple component behavior that I'd like to mimic is shown here):
<template>
<div id="app">
<div class="wrapper">
<Sidebar/>
<div class="container-fluid">
<TopNav/>
<MobNav/>
<div class="container-fluid">
<PageHead/>
<router-view></router-view>
</div>
</div>
</div>
</div>
</template>
<script>
import Sidebar from '#/components/Sidebar'
import TopNav from '#/components/TopNav'
import MobNav from '#/components/MobNav'
import PageHead from '#/components/PageHead'
export default {
name: 'App',
components: {
Sidebar,
TopNav,
MobNav,
PageHead
}
}
</script>
From my AddLoad.vue file:
<template>
<div class="add-load">
<div class="content-container container-slim">
<progress-steps/>
<router-link to="#stops">Stops</router-link>
<router-view></router-view>
</div>
</div>
</template>
<script>
import ProgressSteps from '#/components/ProgressSteps'
export default {
name: 'AddLoad',
component: ProgressSteps
}
</script>
Here is a link to a codesandbox, so you can see the full functionality. https://codesandbox.io/s/7k520xk0yq

using Ember-data with JSONApi and opening page in a new tab

I have a page that has pictures (index.js) and when you click a picture, a detail page with bigger version of the picture and its content (pic.js) opens. When I was using hard-coded data, I created a service and put the data in it. By this way, the model hook wasn't skipped when I click a picture. I did it because my links are dynamic {{#link-to}} helper and I saw that model hook gets skipped when you have it. But now, I need to use JSON api to get the data from an URL, when I do it in the index.js there is no problem with displaying it but when I try to open any link in new tab or paste a link in URL bar, model hook doesn't work in pic.js.
//routes/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return Ember.$.getJSON('My jsonApi Url');
}
});
I read that I need to use ember-data in order to fix it. I created a model "news-list" and put attributes in it. Also I created an adapter and take the code which I call API from index.js and put there.
//adapters/application.js
import JSONAPIAdapter from 'ember-data/adapters/json-api';
import Ember from 'ember';
export default JSONAPIAdapter.extend({
model(params){
return Ember.$.getJSON('My jsonApi Url',params.NewsUrl);
}
});
//templates/index.hbs
{{image-list model=model.Data currentPos=currentPos }}
{{outlet}}
//templates/components/image-list.hbs
{{#each model as |pic|}}
<div>{{#link-to "pic" pic}}
<p class="info">{{pic.Title}}</p><br/>
<img src={{pic.Image}} width="300">
{{/link-to}}</div> {{/each}}
{{yield}}
//routes/pic.js
import Ember from 'ember';
export default Ember.Route.extend({
activate: function() {
this._super(...arguments);
window.scrollTo(0,0);
},
model() {
//return this.store.findAll('news-list');
}
});
//templates/pic.hbs
<p class= "back">{{#link-to 'index'}}Home Page{{/link-to}}</p>
<p class="detail"><img src="{{model.Image}}" width="600" ></p>
<p class="content"><br/><br/>{{model.Content}}</p><br/><br/>
<p class= "back">{{#link-to 'index'}}Home Page{{/link-to}}</p>
{{outlet}}
I tried to use return this.store.findAll('news-list'); in the pic.js but then all I see was a blank page when I click a picture.
I guess there is something I'm missing. I can't use ember-data properly. How can I fix it?

How to switch between login page and app with Aurelia

I'm using the Aurelia skeleton for my project. Everything seemed so intuitive, however I'm stuck with a problem which I suspect is fairly easy (if you know how).
The problem is that the app.html / app.js is initially showing a nav bar and loading some default styles.
Now I need a login page, which does not load anything but its own styles, no navbar no nothing - just its own login form.
So I tried something like this:
app.js
<template>
<div if.bind="auth.isNotAuthenticated()">
<require from="components/login/index" ></require>
<login router.bind="router"></login>
</div>
<div if.bind="auth.isAuthenticated()">
<require from="nav-bar.html" ></require>
<require from="../styles/styles.css"></require>
<div class="container" id="banner">
<div class="row">
<img src="images/logo.png" />
</div>
</div>
<nav-bar router.bind="router"></nav-bar>
<div class="page-host">
<router-view></router-view>
</div>
</div>
</template>
Obviously that doesn't work (unless you refresh the page/f5), since the app.js / app.html is the root route which is always present and never changes. But I hope the logic within the markup helps illustrate what I'm looking to solve?
I guess my if only I knew how to reload the parent route (app.js) when I navigate from the login route, on login success, to another route. And again when I logout, the parent route (app.js) should be refreshed as well once again. Then all my problems would be solved.
What am I missing here? :-)
I think aurelia's setRoot(module) function will help with this.
Here's the standard main.js file that "bootstraps" the aurelia app:
main.js
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
aurelia.start()
.then(a => a.setRoot()); // this is the equivalent of setRoot('app')
}
When setRoot is called with no arguments Aurelia looks for an app.js + app.html viewmodel and view.
We can adjust the logic to check whether the user is logged in and if not, show the login screen:
main.js
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
aurelia.start()
.then(a => {
if (userIsLoggedIn()) {
a.setRoot('app');
} else {
a.setRoot('login');
}
});
}
Then in your login view model you can call setRoot('app') after the user has successfully logged in:
login.js
import {Aurelia, inject} from 'aurelia-framework';
import {AuthService} from './my-auth-service';
#inject(Aurelia, AuthService)
export class Login {
userName = '';
password = '';
constructor(aurelia, authService) {
this.aurelia = aurelia;
this.authService = authService;
}
submit() {
// attempt to login and if successful, launch the app view model.
this.authService.login(userName, password)
.then(() => this.aurelia.setRoot('app'));
}
}
Note: if your app includes a "logout" feature that will send the user back to the login screen (eg setRoot('login')), be sure to reset the router and update the url accordingly. This will prevent issues when the user signs back in. More details in here and here.
For a working example of setRoot you can check also
https://foursails.github.io/sentry
https://github.com/foursails/sentry

Categories

Resources