Vuetify application breaks upon failed v-img source require statement - node.js

Say I have v-img component and I want to render image source using require() statement.
<v-img :src="require(`#/some-folder/my-img.png`)"></v-img>
However, my application breaks completely if I don't have my-img.png in the folder.
So far I've tried:
<v-img :src="require(...) || require(...)"></v-img>
<v-img :src="require(...)">
<template v-slot:placeholder>
// placeholder component.
</template>
</v-img>
<v-img :src="resolveHandler()"></v-img>
methods: {
resolveHandler() {
let image;
try { ... } catch (error) { ... } finally { ... };
return image;
}
}
None of the above worked. Any suggestion please? Thanks.

Try this
<template>
<v-img :src="imageSrc">
<template #placeholder>
No image
</template>
</v-img>
</template>
<script>
export default {
...
mounted() {
try {
this.imageSrc = require(...);
} catch (e) {
this.imageSrc = null;
}
},
};
</script>

Related

How to create blueprint for needle-client-react in Jhipster?

I'm using generator-jhipster and I want to create blueprints for entity-client. After writing entity files, a postWriting function will call addEnitiyToMenu in generator-jhipster/generators/client/needle-api/needle-client-react.js to add new entity generated to file menu/entities.tsx
I need to override this function to write a different entityEntry with original one.
But I can't find the template for it. What should I do?
I found that I can write these function by my own. There is example code if you need
function generateFileModel(aFile, needleTag, ...content) {
return {
file: aFile,
needle: needleTag,
splicable: content,
};
}
function addBlockContentToFile(rewriteFileModel, generator) {
try {
return jhipsterUtils.rewriteFile(rewriteFileModel, generator);
} catch (e) {
console.error(e);
return null;
}
}
function addToMenu() {
if (this.skipClient) return;
if (!this.embedded) {
this.addEntityToModule();
const entityMenuPath = `${this.CLIENT_MAIN_SRC_DIR}app/shared/layout/menus/entities.tsx`;
const entityEntry =
// prettier-ignore
this.stripMargin(`|<Menu.Item key="${this.entityStateName}" icon={<FileOutlined />}>
| <Link to="/${this.entityStateName}">
| ${this.enableTranslation ? `<Translate contentKey="global.menu.entities.${this.entityTranslationKeyMenu}" />` : `${_.startCase(this.entityStateName)}`}
| </Link>
| </Menu.Item>`);
const rewriteFileModel = generateFileModel(entityMenuPath, 'jhipster-needle-add-entity-to-menu', entityEntry);
addBlockContentToFile(rewriteFileModel, this);
}
}
function replaceTranslations() {
if (this.clientFramework === VUE && !this.enableTranslation) {
if (!this.readOnly) {
utils.vueReplaceTranslation(this, [
`app/entities/${this.entityFolderName}/${this.entityFileName}.vue`,
`app/entities/${this.entityFolderName}/${this.entityFileName}-update.vue`,
`app/entities/${this.entityFolderName}/${this.entityFileName}-details.vue`,
]);
} else {
utils.vueReplaceTranslation(this, [
`app/entities/${this.entityFolderName}/${this.entityFileName}.vue`,
`app/entities/${this.entityFolderName}/${this.entityFileName}-details.vue`,
]);
}
}
}

Relay modern pagination without viewer

Hello i have done my server grapqhl api. Currently i'm stack on relay pagination in client. I searched many articles about that. And everywhere pagination done with viewer root query field. Which about it in docs said that field is unnecassary.
In other resourses:
query routesOrdersQuery {
viewer {
...Order_order
}
}
fragment Order_order on OrderType {
orders() #connection {
edges {
node {
}
}
}
In my case:
query routesOrdersQuery {
...Order_order
}
fragment Order_order on Query {
orders(first: $first) #connection(key: "Order_order") {
edges{
node{
id
}
}
}
}
I solved it. Assumption about spreading fragment in root query is not right.
Problem lays in Route render method.
<Route
render={({error, props}) => {
if(error) {
return <div>{error.message}</div>
} else if(props) {
return <Orders query={props} />
} else {
return <div>Loading...</div>
}
}}
...
/>
So use render instead of component. And it should render 3 different states. Otherwise it not work.

Get uid and iterate over an array of objects using Angular4 and Fireabse

I am building a 1-1 chat using Angular4 and Firebase and I am pretty new to Angular.
In order to initiate a conversation, I am trying to display all available users form '/users' subcollection. So, I need to get user/{user.uid}/username.
This is my chat.component.ts:
import { Component, OnInit } from '#angular/core';
import {AngularFireDatabase, FirebaseListObservable} from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { UserSessionService } from '../_services/user-session.service';
#Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.css']
})
export class ChatComponent implements OnInit {
items: FirebaseListObservable<any[]>;
other_users: FirebaseListObservable<any[]>;
user_id: any;
from: any;
msgVal: string = '';
constructor(public afAuth: AngularFireAuth, public af: AngularFireDatabase, public logged_user: UserSessionService ){ }
ngOnInit() {
this.from= this.logged_user.getFirebaseUid();
this.user_id= this.logged_user.getFirebaseUid();
this.items = this.af.list('/personalMessages', {
query: { limitToLast: 5 }
});
this.other_users= this.af.list('/users');
}
findChat(){
this.other_users= this.other_users;
this.user_id = this.user_id;
}
chatSend(theirMessage: string) {
this.items.push({ text: theirMessage, from: this.logged_user.getFirebaseUid(), isRead: false, timestamp: + new Date() });
this.msgVal = '';
this.user_id = this.user_id;
this.other_users= this.other_users;
}
}
And this is my chat.component.html:
<div class="users-chat-container" *ngFor="let other_user of other_users| async">
<div id="circle" style="background-color:pink;">
</div>
<br/> {{other_user.username}}
</div>
<div class="chat-container" *ngFor="let item of items | async">
<div id="circle" style="background-image:url( http://www.ics.forth.gr/mobile/female.png);">
</div>
<br/> {{item.from}}
<p>{{item.text}}</p>
</div>
<input type="text" id="message" placeholder="Type a message..." (keyup.enter)="chatSend($event.target.value)" [(ngModel)]="msgVal" />
How can I iterate over the array of objects I get from '/users' collection? Thank you! :)
you need use ForkJoin. ForkJoin will take users list as input and fire parallel request for all users list
try some thing like this
this.af.list('/users')
.mergeMap((users) => {
if (users.length > 0) {
return Observable.forkJoin(
users.map((user) => this.af.database
.object(`user/${user.$uid}/username`)
.first()
),
(...values) => { // here you can assign username
users.forEach((user, index) => { user.username = values[index]; });
return users;
}
);
}
return Observable.of([]);
});
more info about forkJoin
https://www.learnrxjs.io/operators/combination/forkjoin.html
You need an array for *ngFor. With object.keys you can create an array of the objects. In the example below I have done this with players from a group, coming as objects from firebase.
private getPlayersPerGroup(group: Group) {
this.playersInGroup = [];
if (group["players"]) {
Object.keys(group["players"]).forEach((key) => {
this.groupService.getPlayerById(key).then((player) => {
this.playersInGroup.push(player);
});
});
}
}

Jest/Jasmine .toContain() fails even though matching values are present

I'm writing a simple React application with a Button component, which looks like this:
import React, { Component } from 'react';
// shim to find stuff
Array.prototype.contains = function (needle) {
for (var i = 0; i < this.length; i++) {
if (this[i] == needle) return true;
}
return false;
};
class Button extends Component {
propTypes: {
text: React.PropTypes.string.isRequired,
modifiers: React.PropTypes.array
}
render() {
return(
<span className={this.displayModifiers()}>{this.props.text}</span>
);
}
displayModifiers() {
const modifiers = this.props.modifiers || ["default"];
if (modifiers.contains("default") ||
modifiers.contains("danger") ||
modifiers.contains("success")) {
// do nothing
} else {
// add default
modifiers.push("defualt");
}
var classNames = "btn"
for (var i = 0; i < modifiers.length; i++) {
classNames += " btn-" + modifiers[i]
}
return(classNames);
}
}
export default Button;
I then wrote this to test it:
it("contains the correct bootstrap classes", () => {
expect(mount(<Button modifiers={["flat"]}/>).html()).toContain("<span class=\"btn btn-flat btn-default\"></span>");
});
That code should pass, but I receive the following error message:
expect(string).toContain(value)
Expected string:
"<span class=\"btn btn-flat btn-defualt\"></span>"
To contain value:
"<span class=\"btn btn-flat btn-default\"></span>"
at Object.it (src\__tests__\Button.test.js:42:293)
Any ideas why this is not passing?
From the docs:
Use .toContain when you want to check that an item is in a list.
To test strings you should use toBe or toEqual
it("contains the correct bootstrap classes", () => {
expect(mount(<Button modifiers={["flat"]}/>).html()).toBe("<span class=\"btn btn-flat btn-default\"></span>");
});
But there is a better way of testing the output rendered components: snapshots.
it("contains the correct bootstrap classes", () => {
expect(mount(<Button modifiers={["flat"]}/>).html()).toMatchSnapshot();
});
Note that you will need enzymeToJson for snapshot testing using enzyme.

SWFUpload asp.net return new filename of uploaded files

I'm trying to implement SWFUpload for uploading images on my page. The file-path is stored in a table with a unique id as key and the file is store on the server with a new filename. I need the id or the filename to be returned so that I can access that information when I later-on need it. Is this possible and how is it done? Maybe i could update a asp:label?
I have the following code:
upload.aspx.cs
(I haven't implemented the database saving yet as I want to know if this is possible first)
protected void Page_Load(object sender, EventArgs e)
{
try
{
// Get the data
HttpPostedFile postedfile = Request.Files["Filedata"];
int n = 0;
string fullPath;
while (true)
{
fullPath = Server.MapPath("Img\\") + n.ToString() + RemoveSpecialChars(postedfile.FileName);
if (File.Exists(fullPath))
{
n++;
}
else
{
postedfile.SaveAs(fullPath);
break;
}
}
}
catch
{
// If any kind of error occurs return a 500 Internal Server error
Response.StatusCode = 500;
Response.Write("An error occured");
Response.End();
}
finally
{
Response.End();
}
}
default.aspx
<!--
Image upload
-->
<script type="text/javascript" src="Scripts/swfupload.js"></script>
<script type="text/javascript" src="Scripts/handlers.js"></script>
<script type="text/javascript">
var swfu;
window.onload = function () {
swfu = new SWFUpload({
// Backend Settings
upload_url: "Upload.aspx",
post_params: {
"ASPSESSID": "<%=Session.SessionID %>"
},
// File Upload Settings
file_size_limit: "5120", //5MB
file_types: "*.jpg",
file_types_description: "JPG Images",
file_upload_limit: 0, // Zero means unlimited
// Event Handler Settings - these functions as defined in Handlers.js
// The handlers are not part of SWFUpload but are part of my website and control how
// my website reacts to the SWFUpload events.
swfupload_preload_handler: preLoad,
swfupload_load_failed_handler: loadFailed,
file_queue_error_handler: fileQueueError,
file_dialog_complete_handler: fileDialogComplete,
upload_progress_handler: uploadProgress,
upload_error_handler: uploadError,
upload_success_handler: uploadSuccess,
upload_complete_handler: uploadComplete,
// Button settings
button_image_url: "Style/Images/XPButtonNoText_160x22.png",
button_placeholder_id: "spanButtonPlaceholder",
button_width: 160,
button_height: 22,
button_text: '<span class="button">Välj bilder</span>',
button_text_style: '.button { font-family: Helvetica, Arial, sans-serif; font-size: 14pt; }',
button_text_top_padding: 1,
button_text_left_padding: 5,
// Flash Settings
flash_url: "swfupload.swf", // Relative to this file
flash9_url: "swfupload_FP9.swf", // Relative to this file
custom_settings: {
upload_target: "divFileProgressContainer"
},
// Debug Settings
debug: false
});
}
</script>
default.aspx
<div id="swfu_container" style="margin: 0px 10px;">
<div>
<span id="spanButtonPlaceholder"></span>
</div>
<div id="divFileProgressContainer" style="height: 75px;"></div>
</div>
Thanks.
I found the solution:
If i look inside handlers.js (provided by swfupload) I can catch whats is returned from the upload.aspx.cs
Inside upload.aspx.cs write:
protected void Page_Load(object sender, EventArgs e)
{
try
{
// Get the data
HttpPostedFile postedfile = Request.Files["Filedata"];
Response.Write((postedfile.FileName); //Returns filename to javascript
}
catch
{
// If any kind of error occurs return a 500 Internal Server error
Response.StatusCode = 500;
Response.Write("An error occured");
Response.End();
}
finally
{
Response.End();
}
}
}
Inside handler.js (downloaded from demo page) replace uploadSuccess with:
function uploadSuccess(file, serverData) {
try {
alert(serverData);
addImage("thumbnail.aspx?id=" + serverData);
var progress = new FileProgress(file, this.customSettings.upload_target);
progress.setStatus("Thumbnail Created.");
progress.toggleCancel(false);
} catch (ex) {
this.debug(ex);
}
}

Resources