Vue Router - build from JSON - javascript

I'm quite new to Vue.js. I'm used to vanilla JavaScript.
I need to be able to generate route paths from a JSON file.
How can I achieve it?
EDIT
For example, say this is my JSON:
[
{
"name": "Product 1",
"url": "product-1",
},
{
"name": "Product 2",
"url": "product-2",
}
]
I basically need Vue Router to redirect URL/product-1 to Product 1's component (which will be <Product-1></Product-1>), and URL/product-2 to Product 2's component (<Product-2></Product-2>)

Assuming your component's name is name in the object, we need to match your structure to Vue Router API.
Thus, we can do as follows:
const myRoutes = [
{
"name": "Product 1",
"url": "product-1",
},
{
"name": "Product 2",
"url": "product-2",
}
]
const router = new VueRouter({
routes: myRouters
.map(({name, url})=>({component: name, path: `/${url}`)),
})

Related

Breadcrumbs based on list of nested objects

I am struggling with logic on how to make dynamic breadcrumbs.
I have nested array of objects, and when a user clicks a folder, it adds to the breadcrumbs.
However, currently clicking 2 folders in the same folder adds both folders to the breadcrumbs rather than adding the last clicked folder.
Furthermore, clicking a folder thats deep within the folder tree will not show all previous folders it has passed.
All in all, I just need the logic for breadcrumbs, in javascript.
My attempt is as follows:
Folders.json
[
{
"name": "Documents",
"files": [
{
"name": "Quarterly Results"
}
]
},
{
"name": "Favourites",
"files": [
{
"name": "Brawl Stars",
"files": [
{
"name": "NS dying in 5 seconds"
},
{
"name": "Josiah raping NS"
}
]
},
{
"name": "Coding",
"files": [
{
"name": "Coding is so fun"
},
{
"name": "I love svelte",
"files": [
{
"name": "REPL"
},
{
"name": "oh nooo"
}
]
}
]
},
{
"name": "Favourites 1"
},
{
"name": "Favourites 2"
},
{
"name": "Favourites 3"
}
]
},
{
"name": "Knowledge Base 1"
}
]
Sidebar.svelte
<script>
export let currentFolder
export let currentFolderFlow
export let expanded = false;
export let name;
export let files;
const sideBarFolder = (folderName) => {
if (currentFolder === folderName) {
return false
}
currentFolder = folderName
if (!currentFolderFlow.includes(folderName)) {
currentFolderFlow = [...currentFolderFlow, folderName]
} else {
currentFolderFlow = currentFolderFlow.filter(i => currentFolderFlow.indexOf(i) <= currentFolderFlow.indexOf(folderName))
}
}
</script>
<button class=" pl-1" on:click={() => sideBarFolder(name)}>{name}</button>
Main
<script>
import TreeView from './side-bar.svelte'
let currentFolderFlow = ['Knowledge Base']
let currentFolder = 'Knowledge Base'
</script>
<!-- Breadcrumbs -->
<div class="flex-1 px-3">
<div class="text-md breadcrumbs border rounded-lg p-3">
<ul id="breadcrumbs">
{#each currentFolderFlow as folderFlow}
<li>{folderFlow}</li>
{/each}
</ul>
</div>
</div>
Just a folder name is not enough, for sure. e.g. if you have structure like abc / def / abc, you are in folder def and click on its child abc, it will crop to the root abc folder.
There are different ways to solve it.
Create some kind of unique ID for each folder and pass it. Thus, you'll have to scan for it each time, which will take much time.
Have a parent property in each folder, which will link to the parent object. And pass the folder object instead of its name.
You can pass an array of names: sideBarFolder(["Favourites", "Coding", "I love svelte"]). But to get the array, you'll have to use method 1 or 2 anyway, probably.

Javascript/React code - control/page won't render in fileReader.onload

I have a react page and one of my inputs is a file upload. When loading, I want to read in the file (it's JSON) and then show the file as a tree to allow my users to select nodes (rules) to run against another dataset. BUT, when I pick the JSON file and the 'onload' event handler actually fires off, the page just stops rendering, I get a blank screen. I'm not sure why, I can't see any errors, but I AM IGNORANT with react and kinda new with javascript as well. So, this is quite likely just a dumb thing I'm doing. Can someone point me at what I'm doing wrong here?
handleRules(event) {
const ruleRdr = new FileReader();
ruleRdr.onload = async (e) => {
const rBuf = (e.target.result);
const rData = JSON.parse(new TextDecoder().decode(rBuf));
// the data is there, but it's not mapping into the tree...!?!?!?
const tree = {
name: "QA/QC Rules",
id: 1,
toggled: true,
children: rData.map((wFlow, index) => ({
name: wFlow.WorkflowName,
id: index,
children: wFlow.Rules.map((rule, idx) => ({
name: rule.RuleName,
id: idx
}))
}))
};
this.setState({ ruleData: rData, hasRules: true, treeData: tree });
}
ruleRdr.readAsArrayBuffer(event.target.files[0]);
}
EDIT #1: I don't think it's the code above now, I think it might be my tree library (react-treebeard) or my ignorance on how I'm using it. The code produces what I think is useable data, but it isn't rendering it out.
{
"name": "QA/QC Rules",
"id": 1,
"toggled": true,
"children": [
{
"name": "COMP",
"id": 0,
"children": [
{
"name": "ParentMustHaveCat",
"id": 0
},
{
"name": "ParentMustHaveMfg",
"id": 1
},
{
"name": "ParentMustHaveFamily",
"id": 2
},
{
"name": "SymbolsMustHaveFamily",
"id": 3
}
]
},
{
"name": "PNLCOMP",
"id": 1,
"children": [
{
"name": "ParentMustHaveCat",
"id": 0
},
{
"name": "ParentMustHaveMfg",
"id": 1
},
{
"name": "ParentMustHaveFamily",
"id": 2
},
{
"name": "SymbolsMustHaveFamily",
"id": 3
}
]
},
{
"name": "PNLTERM",
"id": 2,
"children": [
{
"name": "ParentMustHaveCat",
"id": 0
},
{
"name": "ParentMustHaveMfg",
"id": 1
},
{
"name": "ParentMustHaveFamily",
"id": 2
},
{
"name": "SymbolsMustHaveFamily",
"id": 3
}
]
}
]
}
I figured it out. I switched to MUI since it has more components that I will want to use anyway. I got a similar issue with it as well and realized that I have duplicate IDs between the parent and the children, and was creating a kind of lock when trying to compare parent and child IDs in the MUI library. Totally on me - I'm dumb.

How to work with REST API using Ember data?

I'm trying to use ember data with REST API from server. The project is quiet simple and works fine with Fetch API, but i would like to implement the same result using Ember data and understand it's principles. I could not use ember twiddle with this configuration. Below will be the main parts of the project. It was made by Ember CLI version 4.0.1.
The JSON responce from url http://localhost:3000/api/v1/items looks like:
[
{
"id": 1,
"name": "Item 1",
"description": "12345",
"created_at": "2022-01-07T11:43:21.755Z",
"updated_at": "2022-01-07T11:43:21.755Z"
},
{
"id": 2,
"name": "Item 2",
"description": "22222",
"created_at": "2022-01-07T11:43:29.787Z",
"updated_at": "2022-01-07T11:43:29.787Z"
},
{
"id": 3,
"name": "Item 3",
"description": "33333",
"created_at": "2022-01-07T11:43:37.885Z",
"updated_at": "2022-01-07T11:43:37.885Z"
}
]
The responce from a single item request such as http://localhost:3000/api/v1/items/1:
{
"id": 1,
"name": "Item 1",
"description": "12345",
"created_at": "2022-01-07T11:43:21.755Z",
"updated_at": "2022-01-07T11:43:21.755Z"
}
app/models/item.js:
import Model, { attr } from '#ember-data/model';
export default class ItemModel extends Model {
#attr name;
#attr description;
}
app/routes/items.js:
import Route from '#ember/routing/route';
import { inject as service } from '#ember/service';
export default class ItemsRoute extends Route {
#service store;
async model() {
return this.store.findAll('item');
}
}
app/routes/item.js:
import Route from '#ember/routing/route';
import { inject as service } from '#ember/service';
export default class ItemRoute extends Route {
#service store;
async model(params) {
return this.store.findRecord('item', params.id);
}
}
app/templates/items.hbs:
{{#each #model as |item|}}
<LinkTo #route='item' #model={{item}}>{{item.name}}</LinkTo>
{{/each}}
app/adapters/application.js:
import RESTAdapter from '#ember-data/adapter/rest';
export default class ItemAdapter extends RESTAdapter {
host = 'http://localhost:3000';
namespace = 'api/v1';
buildURL(...args) {
return `${super.buildURL(...args)}.json`;
}
}
app/serializers/application.js:
import RESTSerializer from '#ember-data/serializer/rest';
export default class ItemSerializer extends RESTSerializer {}
app/router.js:
import EmberRouter from '#ember/routing/router';
import config from 'dist/config/environment';
export default class Router extends EmberRouter {
location = config.locationType;
rootURL = config.rootURL;
}
Router.map(function () {
this.route('items');
this.route('item', { path: '/:id' });
});
When I move to route /items on the ember client, the following error appears in the console:
WARNING: Encountered "0" in payload, but no model was found for model
name "0" (resolved model name using
<dist#serializer:item::constructor>.modelNameFromPayloadKey("0"))
And the same errors for "1" and "2". The template doesn't render links in the each loop.
Probably, there are some features in Ember data with REST API, and I would really like to figure it out. Thanks for attention!
I believe you have this issue because your data is not in the RESTSerializer format but rather in the JSONSerializer one:
the JSONSerializer expects the response to be a JSON object that looks
similar to this
{
"id": "1",
"title": "Rails is omakase",
"tag": "rails",
"comments": ["1", "2"]
}
So i guess you should just use this one.
If for any reason you wanna keep the RESTSerializer you should return your data similar to this format:
{
"item":
{
"id": 1,
"name": "Item 1",
"description": "12345",
"created_at": "2022-01-07T11:43:21.755Z",
"updated_at": "2022-01-07T11:43:21.755Z"
}
}
or for a list
{
"items": [
{
"id": 1,
"name": "Item 1",
"description": "12345",
"created_at": "2022-01-07T11:43:21.755Z",
"updated_at": "2022-01-07T11:43:21.755Z"
},
...
]

Path with '/' in json-server db.json

i use server-json to have a fake API, i have the path "playbook/active" in data.json
"playbook/active": [{
"description": "This playbook will install haproxy",
"name": "Testing playbook 3",
"tag": [
"loadbalancer",
"charge"
],
"path": "/etc/ansible/haproxy.yml",
"type": "action",
"id": "4bb107be-9efe-11e9-b3e5-bc5ff4901aa5"
},
{
"path": "google.com",
"description": "This is the playbook before execution",
"tag": [
"webserver",
"tomcat"
],
"id": "faa746b4-9cb7-11e9-9b94-bc5ff4901aa5",
"name": "mysql"
}
]
but i have this error
Error: Oops, found / character in database property 'playbook/active'.
I change to "playbook/active" but same error
Providing a complete answer (showcase example)
Configuring db.json and routes.json can do the trick for you:
db.json
{
"playbookActive": [
{
"id": 1,
"name": "Active Playbook 1",
"description": "Description 1"
},
{
"id": 2,
"name": "Active Playbook 2",
"description": "Description 2"
}
]
}
routes.json
{
"/playbook/active": "/playbookActive",
"/playbook/active/:id": "/playbookActive/:id"
}
Note: the mapping in routes.json is goes like this: [expanded/endpoint]: aliasEndpoint where aliasEndpoint should match the one from db.json.
package.json
{
...
"scripts": {
"api": "json-server [path-to-db.json] --routes [path-to-routes.json] --no-cors=false"
},
...
}
Verify the routing on start (logs from npm run api):
Resources
http://localhost:3000/playbookActive
Other routes
/playbook/active -> /playbookActive
/playbook/active/:id -> /playbookActive/:id
Home
http://localhost:3000
Examples
GET → http://localhost:3000/playbook/active
Response contains a list with all the active playbooks:
[
{
"id": 1,
"name": "Active Playbook 1",
"description": "Description 1"
},
{
"id": 2,
"name": "Active Playbook 2",
"description": "Description 2"
}
]
GET → http://localhost:3000/playbook/active/2
Response contains the active playbook that matches id=2:
{
"id": 2,
"name": "Active Playbook 2",
"description": "Description 2"
}
Check the error message:
Oops, found / character in database property 'dossier/la'.
/ aren't supported, if you want to tweak default routes, see
https://github.com/typicode/json-server/#add-custom-routes
It seems that slashes are not supported.
The solution is to create a routes.json file containing the mapping for your url.
For example the contents of this file could be:
{
my-awesome-endpoint": "playbook/active"
}
For example:
db.json
"list": [
{
"name": "abcde",
"tel": "123454323",
"id": 5
}
]
routes.json
{
"/v1/list?type=hot": "/list"
}
start command:
npx json-server --watch db.json --routes routes.json

Simple explanation about how to create Relationships with Mongoose

I am new to Mongo db/Mongoose, this question is about mongoose and relationships between collections, I know there's a lot of tutorials about how to make this work but still not able to understand an easy way to make this work. I have a two models:
This is the main model:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var CategorySchema = new Schema({
name : String,
info : String,
items : [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});
var itemsSchema = Schema({
name : String,
description : String,
price : Number
});
var Item = mongoose.model('Item', itemsSchema);
module.exports = mongoose.model('Category', CategorySchema);
I need to populate items array inside category collection and create the relationship between the two collections.
When I a post from postman I can see the items array getting created but I am not able to populate the array.
If I do get categories, this is the response:
[
{
"_id": "564120be4123198a1f93feb5",
"name": "Classic",
"info": "this is the info",
"__v": 0,
"items": []
},
{
"_id": "5641220b02968e901f678ff5",
"name": "Classic",
"info": "this is the info",
"__v": 0,
"items": []
}
]
This is the put result to api/categories/
{
"_id": "564120be4123198a1f93feb5",
"name": "test again",
"info": "this is the info",
"__v": 1,
"items": []
}
Desired output:
{
"_id": "564120be4123198a1f93feb5",
"name": "test again",
"info": "this is the info",
"__v": 1,
"items": [
{
"_id": "some id"
"name": "name",
"description": "lorem ipsup"
},
{
"_id": "some id"
"name": "name",
"description": "lorem ipsup"
},
{
"_id": "some id"
"name": "name",
"description": "lorem ipsup"
},
]
}
Even if you've a reference in Category, you should use populate method to inform mongoose that you want him to retrieve the referenced items.
Something like:
var Category = require('./category.model');
Category.find().populate("items");
if you want to populate only one field of item model you can add it ine parameter of populate:
Category.find().populate("items","name");
I don't know what you want to achieve but it seems to me that the other way could be more beneficial (having a reference to category into item model).

Categories