How to access polymer when "this" becomes "that" - polymer

I am trying to integrate dropzone.js and cloudinary into Polymer 1.0. It does work, but I am hitting a stumbling block on how to send the dynamic URL generated by Cloudinary back to Polymer so I can write that URL into Firebase. I am inside a function listening to dropzone events with the intention of using iron-signals to signal a different web component. "this" is now scoped to dropzone.js and not Polymer.
..resulting in "Uncaught TypeError: this.fire is not a function".
The code is below, I am trying to start the iron-signal based on listening the dropzone.js "success" event which provides access to the new image URL.
<link rel="stylesheet" href="../../../bower_components/dropzone/dist/min/dropzone.min.css">
<dom-module id="my-dropzone">
<style>
:host {
display: block;
}
div#my-dropzone-area {
max-width=300px;
height=300px;
border: 4px dashed blue;
}
</style>
<template>
<paper-button on-tap="startTheMessage">Test Fire!</paper-button>
<iron-signals on-iron-signal-hello="passTheMessage">
<div class="dropzone" id="my-dropzone-area">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
</div>
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'my-dropzone',
ready: function() {
// access a local DOM element by ID using this.$
Dropzone.options.myDropzoneArea = {
paramName: 'file', // The name that will be used to transfer the file
maxFilesize: 10, // MB
uploadMultiple: false,
acceptedFiles: '.jpg,.png,.jpeg,.gif',
parallelUploads: 6,
addRemoveLinks: true,
url: 'https://api.cloudinary.com/v1_1/remarkable-ky/image/upload',
init: function() {
this.on('addedfile', function(file) {
console.log('Added file.');
console.log(file);
});
this.on('sending', function(file, xhr, formData) {
console.log('Sending file.');
formData.append('api_key', 0000000000000);
formData.append('timestamp', Date.now() / 1000);
formData.append('upload_preset', 'where-ky');
});
this.on('success', function(file, response) {
var baseURL = 'http://res.cloudinary.com/remarkable-ky/image/upload/';
var url = baseURL.concat(response.public_id);
console.log('Cloudinary URL: ', url);
this.fire('iron-signal', {
name: 'hello',
data: null
});
});
}
};
},
startTheMessage: function() {
this.fire('iron-signal', {
name: 'hello',
data: null
});
},
passTheMessage: function() {
alert("got it");
},
properties: {},
});
})();
</script>
<script src="../../../bower_components/dropzone/dist/min/dropzone.min.js"></script>

you can pass this into the function with the .bind() function.
this.on('success', function(file, response) {
var baseURL = 'http://res.cloudinary.com/remarkable-ky/image/upload/';
var url = baseURL.concat(response.public_id);
console.log('Cloudinary URL: ', url);
this.fire('iron-signal', {
name: 'hello',
data: null
});
}.bind(this));

Related

Get the event response of script in WebView to the react native

I am using the html script for showing some module. Everthing was going perfect until I got no any response of the eventHandler. How can I get the response of the eventHandler in Web View.I am not getting any log of the onSuccess, onError or onClose methods. I am using react-native-webview. I tried using window.postMessage('onSuccess'); and geting the value on onMessage
this.khaltiUI = `<html>
<head>
<script src="https://khalti.com/static/khalti-checkout.js"></script>
</head>
<body>
<script>
var config = {
// replace the publicKey with yours
"publicKey": "test_public_key_dc74e0fd57cb46cd93832aee0a390234",
"productIdentity": "1234567890",
"productName": "Dragon",
"productUrl": "http://gameofthrones.wikia.com/wiki/Dragons",
"eventHandler": {
onSuccess (payload) {
window.postMessage('onSuccess');
console.log(payload);
},
onError (error) {
window.postMessage('onError')
console.log(error);
},
onClose () {
window.postMessage('onClosed')
console.log('widget is closing');
}
}
};
var checkout = new KhaltiCheckout(config);
checkout.show({amount: 1000, mobile: 9800000000});
</script>
</body>
</html>`
And in the react-native webView component:
<WebView
source={{html: this.khaltiUI }}
originWhitelist={["*"]}
scalesPageToFit={false}
style={{position: 'absolute', top: 0, bottom: 0, right: 0, left: 0}}
onMessage={this.onMessage}
startInLoadingState ={true}
/>
onMessage(event){
console.log('Hello'); //got no any response
console.log(JSON.parse(event.nativeEvent.data));
console.log(event.nativeEvent.data);
}
this what I use for sending data from webview to react-native:
react:
import React, { Component } from "react";
import { WebView } from "react-native-webview";
export default class App extends Component {
_bridge(event) {
if(event.nativeEvent.data == 'exit') {
BackHandler.exitApp();
}
}
render() {
return (
<WebView
style={{flex: 1}}
source={{ uri: "https://www.kende.com/" }}
onMessage={event => { this._bridge(event); }}
/>
);
}
}
html:
<script>
$( document ).ready(function() {
$('#exit').on('click', function(){
window.ReactNativeWebView.postMessage("exit");
});
});
</script>
<span id="exit">Exit</span>
To post data to a web page, first, you have to get the ref of WebView:
<WebView
ref={(webView) => this.webView = webView}
onMessage={this.onMessage}
...
/>
Then post a message like:
sendPostMessage() {
console.log("Sending post message");
this.webView.postMessage("Post message from react native");
}

Initializing Google Maps inside component but inside certain element

I using this tutorial to use Google maps API https://markus.oberlehner.net/blog/using-the-google-maps-api-with-vue/ and it is working well. But it use this.$el to load the Google map instance inside the component and that makes take all screen, I want to load inside .map instead so I can have smaller map.
<template>
<div class="container-fluid">
init map
<div class="map">
</div>
</div>
</template>
<script>
import ProgressSpinner from '.././Preloader';
import { mapGetters } from 'vuex'
import gmapsInit from '../.././utils/gmaps';
export default {
name: 'Tracking',
data: () => ({
}),
async mounted() {
$('.container-fluid').bootstrapMaterialDesign();
try {
const google = await gmapsInit();
const geocoder = new google.maps.Geocoder();
const map = new google.maps.Map(this.$el);
geocoder.geocode({ address: 'Austria' }, (results, status) => {
if (status !== 'OK' || !results[0]) {
throw new Error(status);
}
map.setCenter(results[0].geometry.location);
map.fitBounds(results[0].geometry.viewport);
});
} catch (error) {
console.error('Error with calling Google maps API: ',error);
}
},
computed: {
...mapGetters([])
},
created(){
this.$store.dispatch ('allPoints')
.then(()=> console.log('points'))
.catch( () => console.log('no poiints ') )
},
methods: {
},
components: {
ProgressSpinner
}
}
</script>
<style scoped>
.map {
width: 150px;
}
</style>
The problem with style, so I should have added height to the .map element.

How to access a JSON value with Vue.js without using v-for

I have the following json:
[{id: 3,
pais: "Chile",
fuso_atual: "-3",
fuso_api: "-7200",
dst: "1",
dst_start: "1476586800",
dst_end: "1487469599",
created_at: null,
updated_at: "2016-12-11 19:19:11"
}]
and I want to access this properties, but without using v-for or something like this, I want a simple access (in my html) like {{paises[0].pais}}, but when I try this, I get an error "Cannot read property 'pais' of undefined(…)"
My component:
var getTimeZone = {
template: '#time-zone-list-template',
data: function(){
return {
paises: []
}
},
created: function(){
this.getTimeZone2();
},
methods: {
getTimeZone2: function(){
this.$http.get('api/paises').then((response) => {
this.paises = response.body;
});
}
}
};
var app = new Vue({
el: '#app',
components: {
'time-zone-list': getTimeZone
}
});
My html:
<div id="app">
<time-zone-list></time-zone-list>
</div>
<template id="time-zone-list-template">
<div class="time-and-date-wrap">
{{ paises[0].pais }}
</div>
</template>
Any idea?
edit: I can access {{ paises[0] }} with success, but not .pais
edit2: If I use v-for I can navigate in the inside properties
Thanks
I found another solution =>>> v-if="paises.length" this solved my problem =]
var getTimeZone = {
template: '#time-zone-list-template',
data: function(){
return {
paises: []
}
},
created: function(){
this.getTimeZone();
},
methods: {
getTimeZone: function(){
this.$http.get('api/paises').then((response) => {
this.paises = response.body;
});
}
}
};
Then in my template
<template id="time-zone-list-template">
<div class="time-and-date-wrap" v-if="paises.length">
{{ paises[0].pais }}
</div>
</template>
Jeff Mercado's answer in the comment correctly describes why this fails.
You could add a computed property like this...
var getTimeZone = {
template: '#time-zone-list-template',
data: function(){
return {
paises: []
}
},
created: function(){
this.getTimeZone2();
},
computed: {
elPrimerPais: function() {
return this.paises.length > 0 ? this.paises[0].pais : '';
}
},
methods: {
getTimeZone2: function(){
this.$http.get('api/paises').then((response) => {
this.paises = response.body;
});
}
}
};
Then in your template you can do this..
<template id="time-zone-list-template">
<div class="time-and-date-wrap">
{{ elPrimerPais }}
</div>
</template>

Jquery Mobile when redirecting or changing url, pages does not have any css

I am working with a backbone, jquery mobile, express app. Everything looks fine when the app starts and works correctly, however, when I click a link or change the url the html renders correctly but no jquery mobile magic appears. It only renders in the login part with a header and footer and format, but when the url changes and I come back, the page loses its css or jquery mobile magic.
define(['views/index', 'views/register', 'views/login', 'views/forgotpassword', 'views/profile',
'views/vinbookDoc', 'models/Account', 'models/Vinbook', 'models/vinBooksCollection'],
function(IndexView, RegisterView, LoginView, ForgotPasswordView, ProfileView,
vinbookDocView, Account, Vinbook, vinBooksCollection) {
var AppRouter = Backbone.Router.extend({
currentView: null,
routes: {
"index": "index",
"login": "login",
"desk/:id": "desk",
"profile/:id": "profile",
"register": "register",
"forgotpassword": "forgotpassword",
"vinbook/:id": "showVinbook"
},
initialize: function(){
$('.back').live('click', function(event) {
window.history.back();
return false;
});
this.firstPage = true;
},
showVinbook: function(id) {
var getCollection = new vinBooksCollection();
getCollection.url = '/accounts/me/vinbook';
this.changeView( new vinbookDocView({
collection: getCollection,
id: id
}));
getCollection.fetch();
},
changeView: function(page) {
this.currentView = page;
$(this.currentView.el).attr('data-role', 'page');
this.currentView.render();
$('body').append($(this.currentView.el));
var transition = $.mobile.defaultPageTransition;
// We don't want to slide the first page
if (this.firstPage) {
transition = 'none';
this.firstPage = false;
}
$.mobile.changePage($(this.currentView.el), {changeHash:false, transition: transition});
},
index: function() {
this.changeView(new IndexView() );
},
desk: function (id){
var model = new Account({id:id});
this.changeView(new ProfileView({model:model}));
model.fetch({ error: function(response){ console.log ('error'+JSON.stringify(response)); } });
console.log('works');
},
profile: function (id){
this.changeView(new IndexView() );
},
login: function() {
this.changeView(new LoginView());
},
forgotpassword: function() {
this.changeView(new ForgotPasswordView());
},
register: function() {
this.changeView(new RegisterView());
}
});
return new AppRouter();
});
require
require.config({
paths: {
jQuery: '/js/libs/jquery',
jQueryUIL: '/js/libs/jqueryUI',
jQueryMobile: '/js/libs/jqueryMobile',
Underscore: '/js/libs/underscore',
Backbone: '/js/libs/backbone',
models: 'models',
text: '/js/libs/text',
templates: '../templates',
jqm: '/js/jqm-config',
AppView: '/js/AppView'
},
shim: {
'jQueryMobile': ['jQuery', 'jqm' ],
'jQueryUIL': ['jQuery'],
'Backbone': ['Underscore', 'jQuery', 'jQueryMobile', 'jQueryUIL'],
'AppView': ['Backbone']
}
});
require(['AppView' ], function(AppView) {
AppView.initialize();
});
login
define(['AppView','text!templates/login.html'], function(AppView, loginTemplate) {
window.loginView = AppView.extend({
requireLogin: false,
el: $('#content'),
events: {
"submit form": "login"
},
initialize: function (){
$.get('/login', {}, function(data){});
},
login: function() {
$.post('/login', {
email: $('input[name=email]').val(),
password: $('input[name=password]').val()
},
function(data) {
console.log(data);
if (!data.error){window.location.replace('#desk/me');}
}).error(function(){
$("#error").text('Unable to login.');
$("#error").slideDown();
});
return false;
},
render: function() {
this.$el.html(loginTemplate);
$("#error").hide();
return this;
}
});
return loginView;
});
Just some more details:
When I change from page or the url to another page, a flash of the rendered website appears and then the css or design disappears.
I think this can solve your problem:
$(document).bind('pagechange', function() {
$('.ui-page-active .ui-listview').listview('refresh');
$('.ui-page-active :jqmData(role=content)').trigger('create');
});

dojo 1.7.2+ require custom module

I have written a custom modyle, for example it is printing "Hello World" to the console.
require([
"dojo/_base/declare"
],
function(declare) {
return [
declare("Hello", null, {
printHello : function() {
console.log("Hello, World!");
}
})
];
}
);
And the name of the .js file is "Hello.js". In my html page I need this module, but I have a problem with loading it. My code:
<script type="text/javascript">
var dojoConfig = {
async : true,
parseOnLoad : false,
isDebug : true,
packages: [
{ name: "gui", location: "/scripts/gui" }
]
};
require([
"gui/common/Hello"
],
function(HelloFunciton) {
var hello = new Hello();
hello.printHello();
});
</script>
But I have a error in console:
"NetworkError: 404 Not Found - http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/scripts/gui/common/Hello.js"
It should the javascript file from the localhost...
What might be the problem?
Add baseUrl: "./" to your dojoConfig.
Also make the path to your package relative via ./scripts/gui.
Complete HTML file:
<html>
<head>
<script>
var dojoConfig = {
async: true,
baseUrl: "./",
parseOnLoad: false,
isDebug: true,
packages: [
{ name: "gui", location: "./scripts/gui" }
]
}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js"></script>
<script>
require(["gui/common/Hello"], function(Hello) {
var hello = new Hello();
hello.printHello();
});
</script>
</head>
<body>
</body>
</html>
The module file ./scripts/gui/common/Hello.js:
define([
"dojo/_base/declare"
], function(
declare
) {
return declare([], {
printHello: function() {
console.log("Hello world!");
}
});
});