wait for a job finished to render component in vuejs - socket.io

I have a component here, and I need first to make a request using socket.io :
<template>
<h1>Don't show me before the socket's response</h1>
</template>
<script>
export default {
beforeCreate: function() {
let sessid = this.$cookie.get('sessid')
this.$options.sockets.logout = (data) => {
if (data.redirect) {
this.$router.push(data.redirect)
} else {
console.log('here, you can render the template')
}
}
this.$socket.emit('logout', { sessid })
}
}
</script>
This code works, but it shows the template in browser for a quick moment, before the redirection happens.
I would like to know if there's a tick to wait the socket response for rendering the template.

You can use v-if, when the socket response arrives, you can set a variable which can be used with v-if to not show the HTML, something like following:
<template>
<h1 v-if="sockResp">Don't show me before the socket's response</h1>
</template>
<script>
export default {
data: function() {
return {
sockResp: false
}
},
beforeCreate: function() {
let sessid = this.$cookie.get('sessid')
this.$options.sockets.logout = (data) => {
if (data.redirect) {
this.$router.push(data.redirect)
} else {
console.log('here, you can render the template')
this.sockResp = true
}
}
this.$socket.emit('logout', { sessid })
}
}
</script>

Related

Showing data after hard refresh

im working with vue & laravel.i have a edit profile page with some forms in it(name,email,...)
the default value of this form not showing for the first time, but if user refresh the page everything will be work!!!
<template>
<label>Name:</label>
<input type="text" v-model="name">
<label>Email:</label>
<input type="email" v-model="email">
<template>
<script>
export default {
data () {
return {
name:'',
email:'',
}
},
mounted : function(){
this.getVueItems();
},
methods: {
getVueItems: function(){
axios.get('./api/auth/me').then(response => {
var vm = this;
vm.name = response.data.name;
vm.email = response.data.email;
});
},
getAuthUser () {
this.user = this.$store.getters.currentUser
},
updateAuthUser () {
this.submiting = true,
axios.put('./api/auth/update', {
name:this.name,
email:this.email,
})
.then(response => {
// this.submiting = false;
location.reload(true);
// success();
})
.catch(error => {
this.submiting = false;
})
},
}
}
</script>
whats is the problem?
As you are using arrow function this keyword is already accessible inside the function.
And for this you should first check in console if you are getting proper response value from api in console.
Hence change your function as below and check once.
async getVueItems() {
await axios.get('./api/auth/me').then(response => {
console.log(response);
this.name = response.data.name;
this.email = response.data.email;
});

My textarea input is not be empty after send message using Vue

I am using laravel and Vue. I have created a messenger application. Everything is done. But I am facing a problem. That is, after press enter button, message goes to the desired person. But the message still be available in the input filed until I refresh the page.
Here is my html code.
<input type="hidden" v-model="conID">
<textarea class="col-md-12 form-control" v-model="msgFrom" #keydown="inputHandler"
style="margin-top: 15px;border: none; resize: none;"></textarea>
Here is my Vue code.
inputHandler(e){
if(e.keyCode === 13 && !e.shiftkey){
e.preventDefault();
this.sendMsg();
}
},
sendMsg()
{
if(this.msgFrom){
axios.post('http://localhost:8000/sendMessage',{
conID:this.conID,
msg:this.msgFrom
})
.then(function(response){
console.log(response.data);
if(response.status===200){
app.singleMsgs = response.data;
}
})
.catch(function (error){
console.log(error);
});
}
Can anyone please help me. Just how I can make textarea empty after sending a message.
Thank's in advance.
should be as easy as clearing it once the message is sent
clear the form with: this.msgFrom = '', because you're doing it within a promise function (and without an arrow function), you need to store the this scope and pass it; usually done using var self = this
example:
inputHandler(e) {
if (e.keyCode === 13 && !e.shiftkey) {
e.preventDefault();
this.sendMsg();
}
},
sendMsg() {
var self = this; // <--- store scope 'this'
if (this.msgFrom) {
axios.post('http://localhost:8000/sendMessage', {
conID: this.conID,
msg: this.msgFrom
})
.then(function(response) {
console.log(response.data);
if (response.status === 200) {
app.singleMsgs = response.data;
self.msgFrom = ''; // <--- and then clear form
}
})
.catch(function(error) {
console.log(error);
});
}
}

Vue js: Is it posible to initialize data through a method?

Basically I want to initialize my vValidNombre field on my form by comparing two values, so It would be nice to use a method, something like this:
<script type="text/javascript">
var avatar = new Vue({
el: '#validaciones',
data: {
vNombre: $('input[name=nombre]').val(),
vValidNombre: validar(),
},
methods: {
validar: function(){
if ('true' == 'true') {
return = true;
}
else {
return false;
}
}
}
})
</script>
This code doesn't work, but is it possible to do something like that?
EDIT: I'm using Vue 2
Not really. When it is initialised, vValidNombre would be undefined. However, you can do something like this with the ready method:
var avatar = new Vue({
el: '#validaciones',
data: {
vNombre: $('input[name=nombre]').val(),
vValidNombre: null,
},
ready: function() {
this.vValidNombre = this.validar();
}
methods: {
validar: function(){
// do something here
// and return it
},
bindDom: function() {
}
},
})

Angular2 - Load binary image data asynchronously inside ngFor

I'm trying to load some images using node's fs module. I have it working on a single image but what is the correct way to do this inside an ngFor loop?
Currently I have:
<div *ngFor="let job of getJobs() | async">
<img src={{readImageFile(job.thumbUrl)}}>
</div>
getJobs() returns an observable from my service.
readImageFile() calls a Meteor server-side method which loads the image data using fs and returns it asynchronously:
readImageFile(url) {
if (url) {
this.call('readImageFile', url, function(err, res) {
if (err) {
console.log(err);
}
else {
console.log('read image file success');
return "data:image/jpg;base64," + res;
}
});
}
}
This doesn't work.. So what is the correct method for asynchronously loading data inside an ngFor loop?
update
I tried with readImageFile(url) | async
readImageFile: function(url) {
var Future = Npm.require('fibers/future');
var myFuture = new Future();
fs.readFile(String(url),
function read(error, result) {
if(error){
myFuture.throw(error);
} else {
myFuture.return(new Buffer(result).toString('base64'));
}
});
return myFuture.wait();
}
This is not a good approach. readImageFile(job.thumbUrl) will be called with each change detection run which is quite often.
This should work
<img [src]="readImageFile(job.thumbUrl) | async">
The | async pipe should prevent change detection calling readImageFile() repeatedly.
Another approach would be to fill an array and bind to this array instead
getJobs() {
this.jobs = /*code to get jobs*/.map(jobs => {
this.images = new Array(jobs.length);
jobs.forEach(item, idx => {
readImageFile(idx, item.thumbUrl);
});
return jobs;
});
}
readImageFile(idx, url) {
if (url) {
this.call('readImageFile', url, (err, res) => {
if (err) {
console.log(err);
}
else {
console.log('read image file success');
this.images[idx] = "data:image/jpg;base64," + res;
}
});
}
}
<div *ngFor="let job of jobs | async; let idx=index">
<img [src]="images[idx]">
</div>

angular-slick carousel not working when using promise

This is driving my crazy, the first angular-slick is not working but the second is just fine, any idea what is going on?
I created a plunkr (in case someone is looking for an example in the future), but my problem is very odd because in my code/realproject is not working so I don't know what the hell is going on, anyway! here is the plunkr: http://plnkr.co/edit/URIbhoVpm1OcLSQqISPs?p=preview
I think the problem is related to the DOM because maybe angular needs to create the html before the carousel is render, I don't know... :(
This is the outcome:
https://db.tt/noc0VgGU
Router:
(function() {
'use strict';
angular
.module('mgxApp.landing')
.config(configFunction);
configFunction.$inject = ['$routeProvider'];
function configFunction($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'app/landing/landing.html',
controller: 'homeCtrl',
controllerAs: 'hC'
});
}
})();
Controller:
(function() {
'use strict';
angular
.module('mgxApp.landing')
.controller('homeCtrl', homeCtrl);
homeCtrl.$inject = ['modalFactory', 'channelFactory'];
function homeCtrl(modalFactory, channelFactory) {
var hC = this;
hC.openAuthModal = modalFactory.openAuthModal;
hC.activeChannels;
channelFactory.allActiveChannels().then(function(activechannels){
console.log(activechannels);
hC.activeChannels = activechannels;
});
hC.w = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
hC.breakpoints = [
{
breakpoint: 768,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
}, {
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
];
}
})();
HTML VIEW:
// NOT WORKING
<slick class="slider single-item" responsive="hC.breakpoints" slides-to-show=3 slides-to-scroll=3>
<div ng-repeat="channel in hC.activeChannels">
{{channel.get("username")}}
</div>
</slick>
// Working fine
<slick class="slider single-item" current-index="index" responsive="hC.breakpoints" slides-to-show=3 slides-to-scroll=3>
<div ng-repeat="i in hC.w">
<h3>{{ i }}</h3>
</div>
</slick>
Factory and Promise:
(function () {
'use strict';
angular
.module('mgxApp.channel')
.factory('channelFactory', channelFactory);
channelFactory.$inject = ['$rootScope', '$q'];
function channelFactory($rootScope, $q) {
var service = {
allActiveChannels : allActiveChannels
};
return service;
function allActiveChannels() {
var deferral = $q.defer();
var User = Parse.Object.extend("_User");
var query = new Parse.Query(User).limit(10);
query.find({
success: function(users) {
console.log(users);
/*for (var i = 0; i < users.length; i++) {
console.log(users[i].get("username"));
}*/
deferral.resolve(users);
},
error: function(error) {
console.warn(error);
deferral.reject();
}
});
return deferral.promise;
}
}
})();
My working code
<div tmob-slick-slider sliderData="" dynamicDataChange="true" class="utilHeightImg marqueeContainer">
<slick id="productCarousel" class="slider" settings="vm.slickAccessoriesConfig" data-slick='{"autoplay ": true, "autoplaySpeed": 4000}'>
<!-- repeat='image' -->
<div ng-repeat="slideContent in vm.slides track by $index" >
<div bind-unsafe-html="slideContent" ></div>
</div>
<!-- end repeat -->
</slick>
</div>
you have to write a directive to reinitialize the slider
angular.module('tmobileApp')
.directive('tmobSlickSlider',['$compile',function ($compile) {
return {
restrict: 'EA',
scope: true,
link: function (scope, element, attrs) {
scope.$on('MarqueesliderDataChangeEvent', function (event, data) {
$compile(element.contents())(scope);
});
}
};
}]);
Write this in your controller
hc.selectView=false; // make this hc.selectView=true when your promise get resolve
$scope.$watch('hc.selectView', function(newValue, oldValue) {
$scope.$broadcast('MarqueesliderDataChangeEvent');
});
I ended up using this solution:
Angular-slick ng-repeat $http get
I'd suggest you to use ng-if on slick element. That will only load slick directive only when data is present just by checking length of data.
Markup
<slick ng-if="ctrl.products.length">
<div ng-repeat="product in ctrl.products">
<img ng-src="{{product.image}}" alt="{{product.title}}"/>
</div>
</slick>

Resources