I have a node.js-app running on the same machine on port 8080 with different channels. The communication between my jQuery-site and my .NET endpoint works perfectly.
My Site:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebSocket-Test</title>
</head>
<body>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
$(function() {
$('button').click(function() {
var socket = io.connect('http://localhost:4000');
socket.on($('#username').val(), function (data) {
console.log(data);
socket.emit('my other event', { my: data });
});
});
});
</script>
<input type="text" id="username" />
<button>connect</button>
</body>
</html>
My node.js-server:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(4000);
var count = 0;
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
setInterval(function () {
socket.emit('daniel', { hello: 'Waited two seconds!'});
}, 2000);
socket.emit('daniel', { hello: 'world' });
socket.emit('stefan', { hello: 'world2' });
socket.on('my other event', function (data) {
console.log(data);
});
});
My question is, how can I emmit a message from my .NET backend via node.js?
After my page is loaded I do have a window.io-object. What is the best approach? Just do an eval on the io-object with emmit and the channel or can I pass an object or json-thing to my node.js-server?
My target is, to send an event-driven message. When a new row is inserted into my MSQL-DB a message should be send to the channels.
One thing that you can do, is simply ping the Node.js server when there's an update with the details. You can do this over straight http/https.
Basically, when .NET updates the db, it can fire off a quick POST to a node.js endpoint with the data package that you want to roll out to users.
Related
I want to update {{info}} value when the API is response.
But I don't know why there could be console log the response but cannot update the variable.
Any mistake I have make?
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue#next"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<p>{{info}}</p>
</div>
</body>
</html>
<script>
const { reactive,createApp, ref } = Vue;
const app = {
setup(){
info="waiting......";
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response))
.then(response => (console.log(response)));
return {info};
}
}
const myVue = Vue.createApp(app).mount("#app");
</script>
here is a working example. If you want to use the composition API you have to make info a reactive variable with ref or reactive.
in this case you have to assign the new data to your reactive variable with the .value notation: info.value = data
composition API
const { createApp, onMounted, ref } = Vue;
const app = createApp({
setup() {
let info = ref('warning...')
onMounted(() => {
fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => response.json())
.then(data => {
info.value = data
});
})
return {
info
}
}
});
app.mount("#app");
<script src="https://unpkg.com/vue#next"></script>
<div id="app">
<p>{{info}}</p>
</div>
options API
Vue.createApp({
data() {
return {
info: 'warning...'
}
},
mounted() {
fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => response.json())
.then(data => {
this.info = data
});
}
}).mount('#options-api')
<script src="https://unpkg.com/vue#next"></script>
<div id="options-api">
<p>{{ info }}</p>
</div>
console log the response but cannot update the variable
you have mixed the style from the composition API with the options API.
your code this.info = response will work with the options API (see my second example.) if you want to use the composition API you have to write info.value = response (see my first example).
note: I use the mounted hook only for demonstration purposes.
one of workaround, using vue 2........
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<p>{{info}}</p>
</div>
</body>
</html>
<script>
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response))
}
})
</script>
I think you need to declare a reactive variable via "reactive" in Vue3.
such as:
enter code hereconst app = {
setup(){
// if your request return a value. otherwise, use as below
// let info = reactive({});
let info = ref("waiting......");
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response))
.then(response => (console.log(response)));
return {info};
}
}
As described in the composition API documentation, you need to use ref.
I.e. your code should be
const info=ref("waiting......");
Otherwise, it is just a normal JavaScript variable, and the "reactive magic" of Vue which re-renders the view does not kick in when you change the value. Please note that in some contexts, Vue does automatically make objects reactive, e. g. for data and props when you use the normal components syntax. But for teh composition API, you have to take care of that yourself.
I am trying to build a React Native app using expo and firebase authentication. The email/password authentication is working fine but the phone number authentication is failing because of the applicationVerifier.
I have tried to use 'react-native-firebase' but that is also not working and giving error.
[Error: RecaptchaVerifier is only supported in a browser HTTP/HTTPS environment with DOM support.]
Thanks.
You need to make .html file and put this code..
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>Entering captcha</title>
</head>
<body>
<p style="text-align: center; font-size: 1.2em;">Please, enter captcha for continue<p/>
<button id="continue-btn" style="display:none">Continue to app</button>
<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase-auth.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "AIzaSyCy6HyqIV5Q_A5lllIxZgePSmKq-Q8eqiw",
authDomain: "onsignledemo.firebaseapp.com",
databaseURL: "https://onsignledemo.firebaseio.com",
projectId: "onsignledemo",
storageBucket: "onsignledemo.appspot.com",
messagingSenderId: "223114260821"
};
firebase.initializeApp(config);
</script> <script>
function getToken(callback) {
var container = document.createElement('div');
container.id = 'captcha';
document.body.appendChild(container);
var captcha = new firebase.auth.RecaptchaVerifier('captcha', {
'size': 'normal',
'callback': function(token) {
callback(token);
},
'expired-callback': function() {
callback('');
}
});
captcha.render().then(function() {
captcha.verify();
});
}
function sendTokenToApp(token) {
var baseUri = decodeURIComponent(location.search.replace(/^\?appurl\=/, ''));
const finalUrl = location.href = baseUri + '/?token=' + encodeURIComponent(token);
const continueBtn = document.querySelector('#continue-btn');
console.log(finalUrl);
// continueBtn.onclick = (event)=>{
// window.open(finalUrl,'_blank')
// }
continueBtn.style.display = "block";
}
document.addEventListener('DOMContentLoaded', function() {
getToken(sendTokenToApp);
});
</script>
</body>
</html>
and put this file in to your running server and load your URL in to react- native Webview before sending confirmation code and after verify this CAPTCHA send confirmation code...
I have a Spring Data Rest backend and in src/main/resources/static html + js assets which work fine. My issue is that I can't understand how to render the data picked up from the webservice in the interface.
In case I set the data explicitly as an array, it works fine (see https://v2.vuejs.org/v2/guide/list.html).
Thank you in advance!
...
const ListFormsApi = {
template: '<div><ul><li v-for=\'item in items\'>{{item.details.Title}}</li></ul></div>',
data: function(){
return {
items: ''
}
},
created: function() {
this.get()
},
methods: {
get: function() {
axiosInstance.get('/contactTemplate')
.then(function (response) {
this.items = response.data._embedded.contactTemplate
}).catch(function (error) {
console.log(error)
}
);
}
}
}
...
The webpage is quite simple and straightforward from documentation examples (assume that complete html and head tags are present as well...
<body>
<div id="app">
<h1><router-link to="/">ContactForm Factory!</router-link></h1>
<p>
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
<router-link to="/listForms">List Forms</router-link>
<router-link to="/listFormsApi">List Forms API</router-link>
</p>
<router-view></router-view>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router#2.0.0/dist/vue-router.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="app.js"></script>
</body>
I think this is happening because scope of this is not what you are expecting inside the then block of axiosInstance, you need to make following change to make it work.
methods: {
get: function() {
var self = this
axiosInstance.get('/contactTemplate')
.then(function (response) {
self.items = response.data._embedded.contactTemplate
}).catch(function (error) {
console.log(error)
}
);
}
You can have a look at my answer on the similar problem here.
When you are registering the .then() callback the context of the function changes.
In order to keep the context you can use the bind method.
methods: {
get: function() {
axiosInstance.get('/contactTemplate')
.then(function (response) {
this.items = response.data._embedded.contactTemplate
}.bind(this)) // added .bind
.catch(function (error) {
console.log(error)
});
}
}
vue-resource is now using response.body rather than data so look to update as follows:
methods: {
get: function() {
axiosInstance
.get('/contactTemplate')
.then((response) => {
this.$set(this.$data, 'items', response.body._embedded.contactTemplate)
})
.catch((error) => {
console.log(error)
});
}
}
I've also used arrow syntax to correct the scope of this and this.$set to ensure the data that you set is reactive.
If this still doesn't produce the desired result I'd confirm the data is correctly returning from the endpoint. Vue-resource has methods such as response.json() available if for instance the server responds with an incorrect content-type.
I've created an application that takes an address or city and displays the most Favorited tweet at that location using Vuejs. I've written three methods for each thing that needs to happen.
First, I grab an auth key from a url fragment. Second,
I pass the address to google's api to get cordinates. Finally, I use the key and location from the first two methods to make the final Api request to get the content I want.
As it stands I have three buttons that appear on the appropriate step and trigger their method with an #click. Is there a way to trigger a sequence of methods with #click? It seems like I may be able to use $emit to chain them together but I am new to developing on the web and don't fully understand what I've read so far.
Id like to just have one button do all three.
My solution as it stands:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<title></title>
</head>
<body>
<div id="app">
<button #click="method1">button 1</button>
<button #click="method2">button 2</button>
<button #click="method3">button 3</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.js">
</script>
<script>
new Vue({
el: "#app",
methods: {
method1: function(){
alert("first thing happened");
},
method2: function(){
alert("second thing happend");
},
method3: function(){
alert("third thing happened")
}
}
});
I think it would be much more easy and intuitive to use a Promise(http://www.html5rocks.com/en/tutorials/es6/promises/). Promises have been around for a while now, but they are not supported by old IE (http://caniuse.com/#feat=promises). You can use a polyfill, though.
I started using them about 6 months ago and they are extremely powerful, and combined with vue-resource (https://github.com/vuejs/vue-resource) they are just amazing. Your code would look like this:
new Vue({
el: "#app",
methods: {
method1: function(){
this.$http(authCallUrl, data1)
.then(function (response) {
console.log('First call was successful', response);
return this.$http(googleApiURL, data2);
})
.then(function (response) {
console.log('Second call was successful', response);
return this.$http(finalAPIRequestURL, data3);
})
.then(function (response) {
console.log('Everything was top-notch', response);
})
}
}
});
I know it seems like a lot of new things but believe me, Promises are gonna improve you life big times!
Cheers!
If you weren't relying on that asynchronous API call, you could have created a method that fired off all three sequentially and bound your #click to that. Because you are waiting on an AJAX call, though, the $emit() and custom event handling is probably the way to go. This will let you pass data between your methods, too (in case your API call is dependent on the result of your auth key extraction, et cetera).
new Vue({
el: "#app",
methods: {
method1: function() {
var resultOfMethod1 = "foo ";
alert( "resultOfMethod1: " + resultOfMethod1 );
this.$emit( "ready.method1", resultOfMethod1 );
},
method2: function( token ) {
var resultOfMethod2 = token + "bar ";
alert( "resultOfMethod2: " + resultOfMethod2 );
this.$emit( "ready.method2", resultOfMethod2 );
},
method3: function( token ) {
var resultOfMethod3 = token + "baz ";
alert( "resultOfMethod3: " + resultOfMethod3 );
}
},
events: {
"ready.method1": function ( token ){
this.method2( token );
},
"ready.method2": function ( token ){
this.method3( token );
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.js"></script>
<div id="app">
<button #click="method1">button 1</button>
</div>
The dojo api doesn't seem to load on my system (IE 8, Windows 7 with IIS 7.5). I try to test these examples by linking to the dojo api like this
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
dojo.require("dojo.lang.*");
dojo.require("dojo.widget.Tree");
</script>
I also downloaded the library to link to it directly like this.
<script type="text/javascript" src="dojo.js">/*_*/</script>
<script type="text/javascript">
dojo.require("dojo.lang.*");
dojo.require("dojo.widget.Tree");
</script>
But got the same result. The library scripts don't load the treeview. Are there issues with IE8, Windows 7 or IIS 7.5 for the dojo libary 1.6.1?
Do you know of a treeview with this functionality: MySQL database support, context menu, add/delete node, hyperlink in tree support?
Thanks.
Complete HTML file where the dojo api doesn't load.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial: Hello Dojo!</title>
<!-- load Dojo -->
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
dojo.addOnLoad() {
dojo.require("dojo.lang.*");
dojo.require("dojo.widget.Tree");
}
</script>
<script type="text/javascript">
var treeDat = {
treeNodes: [
{ title:"World" },
{ title:"Business",
children:[
{ title:"News",
children:[
{ title:"Main"},
{ title:"Company News" },
{ title:"Economy" }
]
},
{ title:"Markets" },
{ title:"Technology" },
{ title:"Jobs and Economy" }
]
},
{ title:"Sports" }
]
};
</script>
<script type="text/javascript">
var TreeBuilder = {
buildTreeNodes:function (dataObjs, treeParentNode){
for(var i=0; i<dataObjs.length;i++){
var node = dojo.widget.createWidget("TreeNode",{
title:dataObjs[i].title,
expandLevel:99,
widgetId:(((treeParentNode)?treeParentNode.widgetId:"root_")+"_"+i)
});
treeParentNode.addChild(node);
treeParentNode.registerChild(node,i);
if(dataObjs[i].children){
this.buildTreeNodes(dataObjs[i].children, node);
}
}
},
buildTree:function (){
var myTreeWidget = dojo.widget.createWidget("Tree",{
widgetId:"myTreeWidget",
DNDMode:"between",
DNDAcceptTypes:["myTreeWidget"]
});
this.buildTreeNodes(treeDat.treeNodes,myTreeWidget);
var treeContainer = document.getElementById("myWidgetContainer");
var placeHolder = document.getElementById("treePlaceHolder");
treeContainer.replaceChild(myTreeWidget.domNode,placeHolder);
}
}
function addTreeContextMenu(){
var djWdgt = dojo.widget;
var ctxMenu = djWdgt.createWidget("TreeContextMenu",{});
ctxMenu.addChild(djWdgt.createWidget(
"TreeMenuItem",{caption:"Add Child Menu Item"}));
ctxMenu.addChild(djWdgt.createWidget(
"TreeMenuItem",{caption:"Delete This Menu Item"}));
document.body.appendChild(ctxMenu.domNode);
var myTree = dojo.widget.manager.getWidgetById("myTreeWidget");
/* Bind the context menu to the tree */
ctxMenu.listenTree(myTree);
}
dojo.addOnLoad(function(){
TreeBuilder.buildTree();
addTreeContextMenu();
});
</script>
</head>
<body>
<h1>Programmatic Dojo Tree Demo</h1>
<hr />
<div id="myWidgetContainer"
style="width: 17em; border: solid #888 1px; height:300px;">
<span id="treePlaceHolder"
style="background-color:#F00; color:#FFF;">
Loading tree widget...
</span>
</div>
</body>
</html>
You need to wrap the dojo.require calls in the dojo.addOnLoad function. This is required when using Dojo cross-domain build.
See more at http://dojotoolkit.org/reference-guide/quickstart/cross-domain.html
dojo.addOnLoad(function() {
dojo.require("dojo.lang.*");
dojo.require("dojo.widget.Tree");
});