Can I get some help the proper setup of history library with react-router, the docs somewhere says that I have to use a mixin to use history from reactrouter but somewhere else tells me that I have to import history library to acomplish the task. It's so confusing
You only need to import the history library if you are going to be changing the default settings for react-router and that's only for when you setup your router. Otherwise, you don't need to.
Regardless, to use history.pushState, you do need to use the mixin. If using React Router 1.0.0-rc3, you would do as follows (a simple example but should get the point across):
var React = require('react');
var History = require('react-router').History;
var Link = React.createClass({
mixins: [ History ],
_handleClick: function(){
this.history.pushState(null, "/example-route");
},
render: function() {
return (
<div onClick={this._handleClick}>
Link
</div>
);
},
});
module.exports = Link;
Related
I need your help when writting good composables in Vue 3. Looking a the documentation I can see that composables should be a function. That's ok.
However I don't feel confortable with this because I lose IDE help and autocompletion.
For example, if I have a useUtils() composable like this:
// composables/useUtils.js
export default function useUtils() {
const isAdmin = () => true;
const isUser = () => false;
return {
isAdmin,
isUser,
}
Then, when writting code in PhpStorm/WebStorn, the IDE does not autocomplete (either auto import) the utilities functions described inside my useUtils() composable :(
For example, if I start to write:
const canCreate = isAdm //<-- Here I would like IDE to autocomplete and autoimport!
That doesn't work because IDE is not able to know what should autocomplete.
Workaround
If I define the composable as a bounch of exported functions however, it works correctly:
// composables/useUtils.js
export const isAdmin = () => true;
export const isUser = () => false;
Now, the IDE knows all available functions and does a good work autocompleting and autoimporting everything.
In addition, when using this approach, I also get's the ability to know what things of my composable are being used and what not, that's very cool. It doesn't happen when deffining a function. But I feel bad because Vue docs says that composables should be a function T_T
So, here is my question:
What do you do guys? Are there a way to configure the IDE for a better integration when writting composables? Is very bad to use a bunch of funtions?
Give me any tip please,
Thanks!
I usually do:
const useMyComposable = () => {
const myData = ref("something");
const myFunction = () => {
// ...
}
return {
myData,
myFunction
}
}
export { useMyComposable };
export default useMyComposable;
So now in a random component I get the autocompletion working.
I loaded my data into kepler.gl (https://kepler.gl/) and created a visual I would like to post online by embedding the code into a blogpost.
However, I want the readers/users not to be able to see and access the side panel, but rather only with the main view of the map.
Is there any way to do so or any parameters I can change when exporting the html?
To solve the issue, one must replace the reducers block:
const reducers = (function createReducers(redux, keplerGl) {
return redux.combineReducers({
// mount keplerGl reducer
keplerGl: keplerGl.keplerGlReducer
});
}(Redux, KeplerGl));
With the following:
const reducers = (function createReducers(redux, keplerGl) {
const customizedKeplerGlReducer = keplerGl.keplerGlReducer.initialState({
uiState: {readOnly: true}
});
return redux.combineReducers({
// mount keplerGl reducer
keplerGl: customizedKeplerGlReducer
});
}(Redux, KeplerGl));
And in the end, change the line with addDataToMap to:
store.dispatch(keplerGl.addDataToMap(loadedData, {readOnly: true}));
ES6's modules are based on a flexible loader architecture (although the standard is not final, so ...).
Does this mean ES6's loader, based on system.js, can load all assets? I.e. CSS, HTML, Images, Text, .. files of any sort?
I ask because I'm starting to use WebComponents & Polymer which have their own HTML import, and implementing them with ES6, which has its own import/loader (system.js).
If you use SystemJS then you can load assets by using plugins:
// Will generate a <link> element for my/file.css
System.import('my/file.css!')
.then(() => console.log('CSS file loaded'));
Alternatively, you can use an import statement. This will make sure that the CSS file is loaded before the your script executes:
import 'my/file.css!';
Finally, you can retrieve the contents of the file using the text plugin:
import cssContent from 'my/file.css!text';
console.log('CSS file contents: ', cssContent);
Another option is to add the css as a dependency in JSPM config files. Basically adding the dependency in the specific package .json file and then running 'jspm install' which will add the override to package.js & jspm.config.js
I know you mentioned ES6 modules, but as that does not appear to support CSS natively, if you're looking for something standards-based to load resources dynamically and wish for something possibly somewhat less unpleasant than XMLHttpRequest, the new Fetch API might be used like this:
var myStylesheets = ['myStyles1.css', 'myStyles2.css'];
Promise.all(myStylesheets.map(url => fetch(url))).
then(arr => Promise.all(arr.map(url => url.text()))).
then(arr => {
var style = document.createElement('style');
style.textContent = arr.reduce(
(prev, fileContents) => prev + fileContents, ''
);
document.head.appendChild(style);
}).then(() => {
// Do whatever now
});
This is even cleaner with async functions:
var myStylesheets = ['myStyles1.css', 'myStyles2.css'];
async function loadStyles(stylesheets) {
let arr = await Promise.all(stylesheets.map(url => fetch(url)))
arr = await Promise.all(arr.map(url => url.text()))
const style = document.createElement('style')
style.textContent = arr.reduce(
(prev, fileContents) => prev + fileContents, ''
)
document.head.appendChild(style);
// Do whatever now
}
loadStyles(myStylesheets)
For other resource types, you can use the blob() method for images, and pending ES6 modules support, eval() for JavaScript, etc.
I faced that question 8 years later :D
In my option, I think is interesting we can use the import.meta.url to be able to load assets relatively in a web scenario. That makes it more similar that esmodules import way.
In addition to the Zamir answer, if the assets/styles are public and we do not have to handle their content, there is no need to use fetch or any ajax at all. Just use HTML tags: link, img, scripts ...
eg: Loading a sibling css file relatively
mywebsite.com
assets
a-component.css
a-component.js
function loadStyle(styleUrl) {
const linkEl = document.createElement("link");
linkEl.setAttribute("rel", "stylesheet");
linkEl.setAttribute("href", styleUrl);
document.head.append(linkEl);
}
function load(currentPath, relativePath) {
// [https:,,,mywebsite.com,assets,a-component.js]
const parts = currentPath.split('/');
// [https:,,,mywebsite.com,assets]
parts.pop();
// [https:,,,mywebsite.com,assets,./a-component.css]
parts.push(relativePath);
// https://mywebsite.com/assets/a-component.css
const absoluteUrl = parts.join('/').replace('/./', '/');
// css
const extension = relativePath.split('.').pop();
switch(extension) {
case 'css':
loadStyle(absoluteUrl);
break;
// others types
}
}
// usage in a-component.js
// https://mywebsite.com/assets/a-component.js
load(import.meta.url, "./a-component.css");
That did help me out in a pure JS Legacy personal project without SystemJS.
I am still learning angularjs so maybe there's something stupid I am not understanding but I have a really strange behaviour when using routing.
In my application I use the following code to define my routes:
var app = angular.module('app', []);
app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider.
when('/pneumatici/:chunka', {}).
when('/pneumatici/:chunka/:chunkb', {});
$locationProvider.html5Mode(true);
}]);
And in a controller I manage them this way:
app.controller('appCtrl', ['$scope', '$route', '$routeParams', '$location', function ($scope, $route, $routeParams, $location) {
$scope.$on('$routeChangeSuccess', function (current,previous) {
if (!($location.path().indexOf('/pneumatici') === -1)) {
$scope.chunka = $route.current.params.chunka; $scope.chunkb = $route.current.params.chunkb;
/** do my stuff with chunka and chunkb **/
} else {
window.location.href = $location.path();
}
});
I have no ngView, no template, nothing.
It works like a charm.
Please note the line where I actually force a page load in case the url is not intended to be managed by the controller appCtrl.
I was forced to do that because once I define my route to catch '$routeChangeSuccess' all links in the page when clicked are catched by angular and no page load occurs even if the link doesn't have the format defined with 'when'.
I would have like to do it with 'otherwise' but I could not understand how to, if doable.
Now the problem.
In the page of course I have links like just '/privacy.html', if I click them the page load is correctly triggered and I do see '/privacy.html' but unfortunately once there if I click the back button I can see the url of the browser changing to (let's say) /pneumatici/foo/bar but no page load is triggered.
Please note in the privacy.html page I have no angular routing defined, there's no .config no .when; there's an anagular app defined, with a controller, but no injection of '$routeProvider' anywhere, no definition of any route.
What is happening? What I am doing wrong?
Thanks for any help!
Update.
I found a viable solution adding:
angular.element("a").prop("target", "_self");
Angular routing is ignored for all 'a' elements with 'target' set to "_self", didn't know that.
Still if I look at this strategy as a whole doesn't sound very elegant to me and I would love to improve it. What I don't like is since I am defining the route in .config I should be able to tell angular to skip any url which do not match the format/path I defined there.
But I don't know if that is doable or not, does anyone know out there?
By turning on html5mode your app should be acting like it should intercept everything on the site by default (from '/'.)
From that perspective, it seems like $location.path() should work in your explicit override, but it isn't really correct ($location.url() would be) and the browser already has the correct URL, so maybe you can't force a reload with location.href = location.href in your specific browser.
Rather than going down that path, I would do the following to make it DRY:
If you add a base href:
<base href="/pneumatici/"></base>
and replace /pneumatici/ with / in your when clause(s):
$routeProvider.
when('/:chunka', {}).
when('/:chunka/:chunkb', {});
then you should just need this:
$scope.$on('$routeChangeSuccess', function (current,previous) {
$scope.chunka = $route.current.params.chunka;
$scope.chunkb = $route.current.params.chunkb;
/** do my stuff with chunka and chunkb **/
});
I think you should let Angular manage all your routes like this:
var app = angular.module('app', []).config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
$routeProvider
.when('/',
{
controller: 'HomeController',
templateUrl: '/partials/home.html'
})
.when('/about',
{
controller: 'AboutController',
templateUrl: '/partials/about.html'
})
.when('/privacy',
{
controller: 'PrivacyController',
templateUrl: '/partials/privacy.html'
})
.when('/404',
{
controller: 'NotFoundController',
templateUrl: '/partials/404.html',
})
.otherwise({
redirectTo: '/404'
});
});
Notice the otherwise above. That tells angular to load the 404 page when a route is not recognized.
I am looking at Node.JS request and notice that you can use
var request = require('request');
request(...)
But when I try to do something similar like in the module I try
exports = function() {}
it does not work. The only way I know to use is
var request = require('request').request;
request(...)
and
exports.request = function() {}
How can I set the whole export to a function instead of adding a function to the export object?
A hint might be available in the request source code but I am finding it hard to figure out what is going on. Can you help?
You need to overwrite it as
module.exports = function() {}
Merely writing exports = function() {} creates a new local variables called exports and hides the exports variable living in module.exports