Can anyone explain what es7 reflect-metadata is all about? - npm

Been studying ES6, JSPM & angular2 for a week now and I found this repo ES6-loader
if we look at the index.html at the bottom script you'll see
System.import('reflect-metadata')
.then(function() {
return System.import('app/index');
})
.catch(console.log.bind(console));
This is using JSPM's systemjs polyfill to get ES6's import.
Question: What is the reflect-metadata really do in this situation? npm reflect-meta The more I read the documentation, the less I understand what it does?

'reflect-metadata' is a package that is a proposal for ES7. It allow for meta data to be included to a class or function; essentially it is syntax sugar.
Example.
Angular 2 ES6:
#Component({selector: "thingy"})
#View({template: "<div><h1>Hello everyone</h1></div>"})
class Thingy{};
As you can see there are no semicolons after #Component and #View. This is because they are essentially Chains of (meta)data on the class.
Now lets look at that same code in Angular 2 but in ES5:
function Thingy(){}
Thingy.annotations = [
new angular.ComponentAnnotation({
selector: "thingy"
}),
new angular.ViewAnnotation({
template: "<div><h1>Hello everyone</h1></div>"
})
];
As you can see the # symbol abstracts out alot of the annotations property of a class and makes it More D.R.Y.
Taking this one step further Angular team knows that annotations are a bit abstract for the new user. Moreover, the ES5 is just too verbose. which is why they made a.js which will make interfacing with annotations better:
Video to understand this

Related

How to add a custom meta data using custom resolvers as PageTitleResolver , PageDescriptionResolver etc

i created a page extending "ContentPageMetaResolver" that implements PageRobotsResolver
export class MyContentPageMetaResolver extends ContentPageMetaResolver implements
PageRobotsResolver {
pageType = PageType.CONTENT_PAGE;
pageTemplate = 'StaticContentPageTemplate';
resolveRobots(): Observable<PageRobotsMeta[]> {
return of(new Array(PageRobotsMeta.NOFOLLOW, PageRobotsMeta.NOINDEX));
}
}
As a result this is adding the the following entry to the head element of the page:
<meta name="robots" content="NOFOLLOW, NOINDEX">
Now i need to do the same thing for keywords. Any idea how to create a custom resolver implementation ?
The PageRobotsResolver interface is provided out of the box in page.resolvers.d.ts file:
/**
* Resolves the robot information for the page. This is used by
* search engines to understand whether the page and subsequential links
* should be indexed.
*
*/
export interface PageRobotsResolver {
/**
* Resolves the robots for the page.
*
* #deprecated since version 1.3
* Use `resolveRobots()` instead.
*/
resolveRobots(...args: any[]): Observable<PageRobotsMeta[]>;
/**
* Resolves the robots for the page.
*/
resolveRobots(): Observable<PageRobotsMeta[]>;
}
And added the following to my providers list of my module :
#NgModule({
providers: [
{ provide: ContentPageMetaResolver, useExisting: MyContentPageMetaResolver }
]
})
PageMetaResolver are used by the PageMetaService to generate page meta data. Specific meta data can be added in a specific resolver (i.e. in your MyContentPageMetaResolver), or you could extend the PageMetaResolver to gather additional metadata for all resolvers.
By default, Spartacus iterates (from feature flag 1.3) over various resolvers, and - if the resolver is implemented – adds the resolved data to the page meta model. This is done in the PageMetaService, and you could (but should not ;), see below) extend the list of resolverMethods in that service so that your custom method is called.
An alternative (but less flexible) approach would be to provide a custom SeoMetaService, and override the meta setter. Also, the SeoMetaService is limited to page meta data, while the PageMetaService can contribute to other areas of the application, such as structural data.
Whether the use of keywords in 2020 is still a good idea, I'd recommend to read up on this, as crawlers seem to stop worrying for this a long time ago. This is the reason why we haven't added a default resolver in Spartacus, but if you come up with good arguments to do so, I'm eager to learn!

Merge styles - How to use vendor prefixes

I'm using this library #uifabric/merge-styles from office-ui-fabric. My question is how to use vendor prefixes inside mergeStyleSets?
Example -webkit-filter:
import { mergeStyleSets } from '#uifabric/merge-styles'
mergeStyleSets({
webkitFilter: 'blur(5px)', // Error! No Typescript definition.
})
Is there any other way to achieve this?
Merge Styles Library
It looks like there is no Typescript definitions for it
IRawStyleBase.ts
Addition to #Vitalie Braga answer:
This is temporary solution if you are using Typescript project:
const foo = mergeStyleSets({
root: [
{
backgroundColor: '#f00',
...({ '-webkit-filter': 'blur(5px)' } as any)
},
]
})
Issues Page - Git OFFICE UI FABRIC
#uifabric/merge-styles library has smarts about automatic vendor prefixing for you but the only issue with that is that the rules that are auto-prefixed today are limited to just one: user-select. I would advise you go and submit an issue in their github repo here and either ask if new rules can be added or ask how to handle this situation.
From a deeper investigation looks like they have some vendor specific support but is very limited in IRawStyleBase.ts. Those rules will automatically be transformed into vendor rules.
So to answer your questions if you are using a TS project there is no way you can specify something that is not compatible with the IRawStyleBase interface but if you are using a js script you can probably try your luck as I did in this code-sandbox and it looks like the filter get's through but nothing else.

Writing an object to the location.hash using Vue.js and URI.js

I have a list of items along with a filter. I'd like to store the filter options in the window.location.hash property, so that I have nice sharable urls.
I am struggling to build a hash fragment which will work, using URI.js.
Vue.js 2.4.4
URI.js 1.19.0
What I've done so far
import Uri from "urijs";
let UriFragment = require('../../node_modules/urijs/src/URI.fragmentURI.js');
// UpdateHash method
let uri = new Uri(window.location.href);
uri.fragment({
providers: ['best', 'bestest'],
sort: 'recommended'
});
window.location.hash = uri.fragment();
What's happening?
example.com/list-of-things#![object Object]
What I expected to happen
As per the docs about 'fiddling with the fragment' http://medialize.github.io/URI.js/
example.com/list-of-things#providers=best&providers=bestest&sort=recommended
Question
How can I ensure that the plugin for URI.js is loaded and working? Then move onto figuring out why it's not outputting a formatted uri fragment.
I knew as soon as I posted, I would find the answer.
I was trying to use code for URI.fragmentURI.js when in fact I wanted URI.fragmentQuery.js.
Swapping to the correct plugin for the library has solved this problem.

Dynamic struct member names like in javascript in golang

I am writing a multi-lang website.
I read the language info from users cookies, and I have several translation modules such as en.go gr.go etc.
The modules are of type map[string]string.The problem here is in javascript I can do something like lang[cookies.lang]["whatever message"].'But go does not support accessing struct members in this way.
I could make switch case ormap[string]map[string]string` and map all possible languages, but this is much extra work.
So is there any way golang provides some way to access members like js brackets notation?
Not: There was a similar question on the stack, and somebody wrote to use "reflect" package, but I could not quite understand how it works and failed to reproduce by myself works and failed to reproduce by myself.
One possible route would be to use a map[string]map[string]string.
You could then have a base package in which you declare your base translation variable and in your translation modules, you can use an init function to populate the relevant sub-map. It's essentially optional if you want to do this as separate packages or just separate files (doing it as packages means you have better compile-time control of what languages to include, doing it as files is probably less confusing).
If you go the packages root, I suggest the following structure:
translation/base This is where you export from
translation/<language> These are "import only" packages
Then, in translation/base:
package "base"
var Lang map[string]map[string]string
And in each language-specific package:
package "<language code>"
import "language/base"
var code = "<langcode>"
func init() {
d := map[string]string{}
d[<phrase1>] = "your translation here"
d[<phrase2>] = "another translation here"
// Do this for all the translations
base.Lang[code] = d
}
Then you can use this from your main program:
package "..."
import (
"language/base"
_ "language/lang1" // We are only interested in side-effects
_ "language/lang2" // Same here...
)
Not using separate packages is (almost) the same. You simply ensure that all the files are in the same package and you can skip the package prefix for the Lang variable.
A toy example on the Go Playground, with all the "fiddly" bits inlined.

How does lodash's modular build work? Or any commonjs modular build work?

It's my understanding that I can
npm install lodash
but then call
require('lodash/collections/each')
and only get that single function without the overhead of loading all of lodash.
How does that work? I can't quite figure it out looking at lodash's package.json.
So it turns out that this is just the normal way you'd require something using node/commonjs syntax.
Imagine if lodash were just another folder on your desktop, you could require the function in this way:
var each = require('./Desktop/lodash/collections/each')
The trick lodash is doing is that they have another file marked as the 'entry' in their package.json that grabs all the different functions from their subdirectories and adds them to the exported lodash object:
//index.js
module.exports = {
each: require('./collections/each'),
keys: require('./object/keys')
...etc
}
Which is why you can also say:
var each = require('lodash').each