Dart web app not accessing MongoDB - mongodb

I am trying to write a simple single-page web app in Dart using the "observatory" package. What it should do is display all the data in the "Name" collection, retrieve the user's input, add lastly that input to both the on-screen list and the collection. The input gets added to the unordered list, but that's all that happens. I'm not sure what I'm doing wrong. Here is my Dart code:
import 'dart:html';
import 'package:objectory/objectory_browser.dart';
class Name extends PersistentObject {
String get collectionName => "Name";
String get first => getProperty("first");
set first(String value) => setProperty("first", value);
String get last => getProperty("last");
set last(String value) => setProperty("last", value);
}
const uri = 'mongodb://localhost/dosdart1';
registerClasses() {
objectory.registerClass(Name, () => new Name(), () => new List<Name>());
}
void main() {
objectory = new ObjectoryWebsocketBrowserImpl(uri, registerClasses, false);
loadNames();
querySelector('#output').text = 'Your Dart app is running.';
var btn = querySelector('#btn');
btn.onClick.listen(addName);
}
Future display(name) {
var completer = new Completer();
name.fetchLinks().then((__) {
var ul = querySelector('#names');
var li = new LIElement()
..appendText("${name.first} ${name.last}");
ul.append(li);
completer.complete(true);
});
return completer.future;
}
loadNames() {
objectory.initDomainModel().then((_) {
return objectory[Name].find();
}).then((names){
return Future.wait(names.map((name) => display(name)));
}).then((_) {
objectory.close();
});
}
addName(MouseEvent e) {
var name = new Name();
InputElement firstElement = querySelector('#first');
InputElement lastElement = querySelector('#last');
name.first = firstElement.value;
name.last = lastElement.value;
objectory.initDomainModel().then((_){
name.save();
return;
}).then((_) {
objectory.close();
});
display(name);
}
And here is my web page:
<!DOCTYPE html>
<!--
Copyright (c) 2015, <your name>. All rights reserved. Use of this source code
is governed by a BSD-style license that can be found in the LICENSE file.
-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="scaffolded-by" content="https://github.com/google/stagehand">
<title>hybrid_dart</title>
<link rel="stylesheet" href="styles.css">
<script async src="main.dart" type="application/dart"></script>
<script async src="packages/browser/dart.js"></script>
</head>
<body>
<div id="output"></div>
<p><label for="first">First name:</label><input type="text" id="first" name="first"></p>
<p><label for="last">Last name:</label><input type="text" name="last" id="last"></p>
<p><button id="btn" name="btn" title="Insert">Insert</button></p>
<ul id="names">
</ul>
</body>
</html>
Does anybody have any ideas?

You need to chain futures to ensure they are executed in order. I don't see for every call if it returns a Future or a sync value therefore I might miss here and there (I added /* await */ where in doubt).
The new async / await feature makes it much easier to work with async code therefore I changed all your then(...) to async/await.
main() async {
objectory = new ObjectoryWebsocketBrowserImpl(uri, registerClasses, false);
await loadNames();
querySelector('#output').text = 'Your Dart app is running.';
var btn = querySelector('#btn');
btn.onClick.listen(addName);
}
Future display(name) async {
await fetchLinks();
var ul = querySelector('#names');
var li = new LIElement()
..appendText("${name.first} ${name.last}");
ul.append(li);
}
Future loadNames() async {
await objectory.initDomainModel();
var names = await objectory[Name].find();
await Future.wait(names.map((name) => display(name)));
/* await */ objectory.close();
}
Future addName(MouseEvent e) async {
var name = new Name();
InputElement firstElement = querySelector('#first');
InputElement lastElement = querySelector('#last');
name.first = firstElement.value;
name.last = lastElement.value;
await objectory.initDomainModel();
name.save();
/* await */ objectory.close();
await display(name);
}
Without async/await it should be like
void main() {
objectory = new ObjectoryWebsocketBrowserImpl(uri, registerClasses, false);
loadNames().then((_) {
querySelector('#output').text = 'Your Dart app is running.';
var btn = querySelector('#btn');
btn.onClick.listen(addName);
});
}
Future display(name) {
return name.fetchLinks().then((__) {
var ul = querySelector('#names');
var li = new LIElement()
..appendText("${name.first} ${name.last}");
ul.append(li);
});
}
Future loadNames() {
return objectory.initDomainModel().then((_) {
return objectory[Name].find();
}).then((names){
return Future.wait(names.map((name) => display(name)));
}).then((_) {
/* return */ objectory.close();
});
}
Future addName(MouseEvent e) {
var name = new Name();
InputElement firstElement = querySelector('#first');
InputElement lastElement = querySelector('#last');
name.first = firstElement.value;
name.last = lastElement.value;
return objectory.initDomainModel().then((_){
name.save();
return;
// if "name.save();" returns a Future this should be
// return name.save();
}).then((_) {
/* return */ objectory.close();
}).then((_) {
return display(name);
});
}

I finally solved the riddle using forcemvc and server-side MongoDB:
library serverweb2;
// add code to names() to retrieve all the names
// change names.html accordingly
import "package:forcemvc/force_mvc.dart";
import "package:objectory/objectory_console.dart";
import 'dart:async';
main(List<String> args) {
objectory = new ObjectoryDirectConnectionImpl('mongodb://127.0.0.1/serverweb2',
registerClasses, false);
var app = new WebApplication();
app.start();
// print('Hello world!');
}
#Controller
class Controllers {
#RequestMapping(value: "/", method: RequestMethod.GET)
String index(req, Model model) {
return "index";
}
#RequestMapping(value: "/names", method: RequestMethod.POST)
Future names(ForceRequest req, Model model) {
objectory.initDomainModel().then((_) {
req.getPostParams().then((params) {
var first = params['first'] as String;
var last = params['last'] as String;
var name = new Name()
..firstName = first
..lastName = last;
name.save();
return objectory[Name].find();
}).then((names) {
model.addAttribute('names', names);
return;
}).then((_){
req.async("names");
objectory.close();
});
});
return req.asyncFuture;
}
}
class Name extends PersistentObject {
String get collectionName => "Name";
String get firstName => getProperty("first_name");
set firstName(String value) {
setProperty("first_name", value);
}
String get lastName => getProperty('last_name');
set lastName(String value) {
setProperty('last_name', value);
}
#override
String toString() => "$firstName $lastName";
}
registerClasses() {
objectory.registerClass(Name, () => new Name(), () => new List<Name>());

Related

How to make a web component return a Proxy (and be extended)

The goal is to have a base class A extending HTMLElement that customizes getters and setters. Then class B would extend class A and do stuff.
The way to do this is by wrapping class A with a proxy (not the instance, but the class) so B can extend A.
I tried to return a Proxy in the constructor, but I get custom element constructors must call super() first and must not return a different object
<!DOCTYPE html>
<body>
<script>
window.onerror = function (error, url, line) {
document.getElementById('error').innerHTML = document.getElementById('error').innerHTML + '<br/>' + error;
};
</script>
<div id="error">Console errors here:<br /></div>
<my-b-element></my-b-element>
<script type="module">
class A extends HTMLElement {
constructor() {
super();
return new Proxy(this, {
get(target, name, receiver) {
let rv = Reflect.get(target, name, receiver);
console.log(`get ${name} = ${rv}`);
// do something with rv
return rv;
},
set(target, name, value, receiver) {
if (!Reflect.has(target, name)) {
console.log(`Setting non-existent property '${name}', initial value: ${value}`);
}
return Reflect.set(target, name, value, receiver);
}
});
}
}
class B extends A {
constructor() {
super();
}
}
customElements.define("my-b-element", B);
document.querySelector('my-b-element').nonExistentProperty = 'value1';
</script>
</body>
</html>
In case it helps anyone, here's how it's done without any proxy.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
class Reactive extends HTMLElement {
#data = {};
connectedCallback() {
this.propertyObserver();
}
propertyObserver() {
const properties = Object.getOwnPropertyDescriptors(this);
// defines the new object properties including the getters and setters
for (let key in properties) {
const descriptor = properties[key];
this.#data[key] = descriptor.value;
descriptor.get = () => this.#data[key];
descriptor.set = (value) => {
const result = this.trap(key, value);
this.#data[key] = typeof result === 'undefined' ? value : result;
}
delete descriptor.value;
delete descriptor.writable;
}
Object.defineProperties(this, properties);
}
trap() {
// placeholder in case the child doesn't implement it
}
}
class Child extends Reactive {
a = 1;
b = 2;
constructor () {
super();
}
connectedCallback() {
super.connectedCallback();
}
trap(key, value) {
// You can return a value to override the value that is set
console.log(`LOG new ${key}: ${value} old: ${this[key]}`);
}
}
customElements.define("x-element", Child);
</script>
</head>
<body>
<x-element></x-element>
<script>
document.querySelector('x-element').a = 20;
</script>
</body>
</html>

Laravel + Vue 3: Upload files with categories

I'm working on uploading multiple files using Laravel and Vue 3. File uploading is doing fine until I added a select tag in the form for the category. I put the category and files into one object so I can pass only 1 parameter. Now in TestController I can get the value of category but giving me error in files.
I need to:
Pass category and files
Read category and files so I can move and save info to database
test.vue
<form #submit.prevent="upload" enctype="multipart/form-data">
<!-- added this tag for category -->
<select v-model="category">
<option v-for="type in categories" :key="type.id" :value="type.id">
{{ type.name }}
</option>
</select>
<input type="file" multiple #change="fileChange">
<button type="submit">Upload</button>
</form>
<script>
import useTest from "../composables/test.js"
import { onMounted } from 'vue'
export default {
setup() {
const { categories, getCategories, uploadFile } = useTest()
onMounted(getCategories)
const attachments = []
const category = 1 // added for category
const upload = async () => {
// const formData = new FormData // without category
// with category, I put inside an object so I can pass only 1 parameter
const form = {
category: category.value,
files: new FormData,
}
// loop to append
Object.keys(attachments).forEach(
// key => formData.append(key, attachments[key]) // without category
key => form.files.append(key, attachments[key]) // with category
)
// call from composable
await uploadFile(form)
}
return {
categories,
category,
upload,
}
},
}
</script>
composable: test.js
import { ref } from 'vue'
import axios from 'axios'
export default function useTest() {
const categories = ref([])
const getCategories = async () => {
let response = await axios.get("/api/fileUpload/")
categories.value = response.data.categories
}
const uploadFile = async (form) => {
// METHOD IS INSIDE TRY CATCH BLOCK
const config = {headers: { 'content-type': 'multipart/form-data' }}
// let response = await axios.post("/api/fileUpload/", form, config)
let response = await axios.post("/api/fileUpload/", form)
console.log(response);
}
return {
categories,
getCategories,
uploadFile,
}
}
TestController
public function store(Request $request)
{
// $uploadFiles = $request; // without category
$uploadFiles = $request['files']; // with category
$uploadFiles = $request['category'];
error_log($uploadFiles);
// error here: Attempt to read property \"files\" on array
foreach ($uploadFiles->file as $file) {
error_log('here');
error_log($file->getClientOriginalName());
error_log($file->getClientOriginalExtension());
error_log($file->getSize());
error_log($file->getMimeType());
error_log(date("m/d/Y H:i:s.",filemtime($file)));
error_log('---------------------');
}
return response()->json(['status'=>'success'], status: 200);
}

Blazored.LocalStorage.ILocalStorageService.GetItemAsync<!0>(string))

I am new for .NET6 and I have created blazor WASM application in .NET 6.its authentication part is JWT authentication. when I am going to store the token into local storage following error is occurred.
blazor.webassembly.js:1 System.AggregateException: One or more errors occurred. (Method not found: System.Threading.Tasks.ValueTask1<!!0> Blazored.LocalStorage.ILocalStorageService.GetItemAsync<!0>(string)) ---> System.MissingMethodException: Method not found: System.Threading.Tasks.ValueTask1<!!0>
Blazored.LocalStorage.ILocalStorageService.GetItemAsync<!0>(string)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[d__8](d__8& stateMachine) in System.Private.CoreLib.dll:token 0x600454a+0x28
at Infrastructure.Manager.Preferences.ClientPreferenceManager.GetPreference() in Infrastructure.dll:token 0x600004d+0xc
at BlSls.Client.Program.Main(String[] args) in BlSls\Client\Program.cs:line 36
--- End of inner exception stack trace ---
my program.cs
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args).AddRootComponents().AddClientServices();
var host = builder.Build();
var storageService = host.Services.GetRequiredService<ClientPreferenceManager>();
if (storageService != null)
{
CultureInfo culture;
var preference = await storageService.GetPreference() as ClientPreference;
}
builder.Services.AddMudServices();
builder.Services.AddTransient<ILocalItemStore,LocalItemStore>();
builder.Services.AddSingleton<IDataConnect, DataConnect>();
builder.Services.AddScoped<Service.InterData>();
await builder.Build().RunAsync();
}
ILocalStorageService.cs
public interface ILocalStorageService
{
event EventHandler<ChangingEventArgs> Changing;
event EventHandler<ChangedEventArgs> Changed;
ValueTask ClearAsync();
ValueTask<bool> ContainKeyAsync(string key);
ValueTask<string> GetItemAsStringAsync(string key);
ValueTask<T> GetItemAsync<T>(string key);
ValueTask<string> KeyAsync(int index);
ValueTask<int> LengthAsync();
ValueTask RemoveItemAsync(string key);
ValueTask SetItemAsync<T>(string key, T data);
}
required DI in import.razor
#inject BL10StateProvider _stateProvider
#inject IAuthenticationManager _authenticationManager
login.razor
<div class="d-block">
<EditForm Model="#_tokenModel" OnValidSubmit="SubmitAsync">
<DataAnnotationsValidator />
<div class="#(f ? "invalid-box":"user-box")">
<InputText placeholder="Username" #bind-Value="_tokenModel.UserName" />
<ValidationMessage For="() => _tokenModel.UserName" />
#*<label class="body-default">Email</label>*#
</div>
<div class="#(f ? "invalid-box":"user-box")">
<InputText type="password" placeholder="Password" #bind-Value="_tokenModel.Password" />
<ValidationMessage For="() => _tokenModel.Password" />
#*<label class="body-default">Password</label>*#
</div>
<div>
<button type="submit" class="btn-block login-btn button-text"> Sign In</button>
</div>
</EditForm>
</div>
login.razor.cs
public partial class Login
{
bool f = false;
private TokenRequest _tokenModel = new();
protected override async Task OnInitializedAsync()
{
var state = await _stateProvider.GetAuthenticationStateAsync();
if (state != new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())))
{
_navigationManager.NavigateTo("/login");
}
await Task.FromResult(0);
}
private async Task SubmitAsync()
{
var result = await _authenticationManager.Login(_tokenModel);
if (result.Succeeded)
{
f = false;
_navigationManager.NavigateTo("/CompanySelection", true);
}
else
{
_tokenModel.Messaage = "UserName Or Password Incorrect";
f = true;
}
}
}
BL10StateProvider.cs
public class BL10StateProvider {
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var savedToken = await _localStorage.GetItemAsync<string>(StorageConstants.Local.AuthToken);
if (string.IsNullOrWhiteSpace(savedToken))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", savedToken);
var state = new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(GetClaimsFromJwt(savedToken), "jwt")));
AuthenticationStateUser = state.User;
return state;
}
}
AuthenticationManager.cs
public class AuthenticationManager{
public async Task<IResult> Login(TokenRequest model)
{
HttpResponseMessage response=null;
try
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), TokenEndpoints.Authenticate))
{
request.Headers.TryAddWithoutValidation("Timestamp", DateTime.Now.Ticks.ToString());
request.Content = JsonContent.Create(model);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
response = await httpClient.SendAsync(request);
}
}
}
catch (Exception exp)
{
model.Messaage = "Login Falied";
model.IsTokenRequestFailed = true;
return await Result.FailAsync("Server Or API Host Not found");
}
//HttpRequestMessage req = new HttpRequestMessage();
//req.Method = HttpMethod.Post;
//req.RequestUri = TokenEndpoints.Authenticate;
//req.
////var response = await _httpClient.PostAsJsonAsync(TokenEndpoints.Authenticate, model);
// var response = await _httpClient.PostAsJsonAsync()
string responseBody = await response.Content.ReadAsStringAsync();
TokenResponse tokenRequest = JsonConvert.DeserializeObject<TokenResponse>(responseBody);
//var result = await response.ToResult<TokenResponse>();
if (tokenRequest.IsSuccess)
{
model.IsTokenRequestFailed = false;
model.Messaage = "Login Successful";
var token = tokenRequest.Token;
var refreshToken = tokenRequest.RefreshToken;
var userImageURL = tokenRequest.UserImageURL;
await _localStorage.SetItemAsync(StorageConstants.Local.AuthToken, token);
await _localStorage.SetItemAsync(StorageConstants.Local.RefreshToken, refreshToken);
if (!string.IsNullOrEmpty(userImageURL))
{
await _localStorage.SetItemAsync(StorageConstants.Local.UserImageURL, userImageURL);
}
((BL10StateProvider)this._authenticationStateProvider).MarkUserAsAuthenticated(model.UserName);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
return await Result.SuccessAsync();
}
else
{
model.Messaage = "Login Falied";
model.IsTokenRequestFailed = true ;
return await Result.FailAsync(tokenRequest.Messages);
}
}
}
please help me to solve this issue using above code sample.
When you are in Main(), before the .RunAsync(), the JavaScript is not yet loaded.
The error is in this line:
var preference = await storageService.GetPreference() as ClientPreference;
Whatever logic you have around this has to be executed later.
One possible place is in the App component, in OnAfterRenderAsync(true):
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var preference = await storageService.GetPreference() as ClientPreference;
...
}
}
But be aware that you first page may already be Initializing and Rendering before you have set that preference.

How to create a CDN server in dotnet core using MongoDB GridFS and AngularJs

We want to create a decoupled file server named CDN in .net core using MongoDB GridFS and angular js.
From various sources I tried my best to solve the issue.
And finally we done this.
I used Visual Studio 2017 and .NETCore 1.1
To do so I follow the followings:
1. Write Code in MongoDB GridFS
create an interface like
public interface IGridFsRepository : IDisposable
{
Task<string> UploadAsync(IFormFile file);
Task<bool> AnyAsync(ObjectId id);
Task<bool> AnyAsync(string fileName);
Task DeleteAsync(string fileName);
Task DeleteAsync(ObjectId id);
Task<GridFSDownloadStream<ObjectId>> DownloadAsync(string fileName);
Task<GridFSDownloadStream<ObjectId>> DownloadAsync(ObjectId id);
object GetAllFilesByContentType(string contentType, int skip, int
take);
object GetAllFiles(int skip, int take);
}
then create MongoDbCdnContext:
public abstract class MongoDbCdnContext
{
public IGridFSBucket GridFsBucket {get;}
protected MongoDbCdnContext(string connectionStringName)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var connectionString =
config.GetConnectionString(connectionStringName);
var connection = new MongoUrl(connectionString);
var settings = MongoClientSettings.FromUrl(connection);
//#if DEBUG
// settings.ClusterConfigurator = builder =>
builder.Subscribe<CommandStartedEvent>(started =>
// {
// Debug.Write(started.Command);
// });
//#endif
var client = new MongoClient(settings);
var database = client.GetDatabase(connection.DatabaseName);
GridFsBucket = new GridFSBucket(database);
}
}
then implement it:
public class GridFsRepository : MongoDbCdnContext,
IGridFsRepository
{
public GridFsRepository() : base("MongoCdn")
{
}
public async Task<string> UploadAsync(IFormFile file)
{
var options = new GridFSUploadOptions
{
Metadata = new BsonDocument("contentType", file.ContentType)
};
using (var reader = new
StreamReader((Stream)file.OpenReadStream()))
{
var stream = reader.BaseStream;
var fileId = await
GridFsBucket.UploadFromStreamAsync(file.FileName, stream,
options);
return fileId.ToString();
}
}
public async Task<bool> AnyAsync(ObjectId id)
{
var filter = Builders<GridFSFileInfo>.Filter.Eq("_id", id);
return await GridFsBucket.Find(filter).AnyAsync();
}
public Task<bool> AnyAsync(string fileName)
{
var filter = Builders<GridFSFileInfo>.Filter.Where(x =>
x.Filename == fileName);
return GridFsBucket.Find(filter).AnyAsync();
}
public async Task DeleteAsync(string fileName)
{
var fileInfo = await GetFileInfoAsync(fileName);
if (fileInfo != null)
await DeleteAsync(fileInfo.Id);
}
public async Task DeleteAsync(ObjectId id)
{
await GridFsBucket.DeleteAsync(id);
}
private async Task<GridFSFileInfo> GetFileInfoAsync(string fileName)
{
var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename,
fileName);
var fileInfo = await
GridFsBucket.Find(filter).FirstOrDefaultAsync();
return fileInfo;
}
public async Task<GridFSDownloadStream<ObjectId>>
DownloadAsync(ObjectId id)
{
return await GridFsBucket.OpenDownloadStreamAsync(id);
}
public async Task<GridFSDownloadStream<ObjectId>>
DownloadAsync(string fileName)
{
return await
GridFsBucket.OpenDownloadStreamByNameAsync(fileName);
}
public IEnumerable<GridFSFileInfoDto> GetAllFilesByContentType(string
contentType, int skip, int take)
{
var filter = Builders<GridFSFileInfo>.Filter
.Eq(info => info.Metadata, new BsonDocument(new
BsonElement("contentType", contentType)));
var options = new GridFSFindOptions
{
Limit = take,
Skip = skip,
};
var stream = GridFsBucket.Find(filter, options)
.ToList()
.Select(s => new GridFSFileInfoDto
{
Id = s.Id,
Filename = s.Filename,
MetaData = s.Metadata,
Length = s.Length + "",
UploadDateTime = s.UploadDateTime,
})
.ToList();
return stream;
}
public IEnumerable<GridFSFileInfoDto> GetAllFiles(int skip, int take)
{
var options = new GridFSFindOptions
{
Limit = take,
Skip = skip,
};
var stream = GridFsBucket.Find(new
BsonDocumentFilterDefinition<GridFSFileInfo<ObjectId>>(new
BsonDocument()), options)
.ToList()
.Select(s => new GridFSFileInfoDto
{
Id = s.Id,
Filename = s.Filename,
MetaData = s.Metadata,
Length = s.Length + "",
UploadDateTime = s.UploadDateTime,
})
.ToList();
return stream;
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
then create a controller in .netcore web api
[EnableCors("AllowAll")]
[ValidateModel]
[Route("api/files")]
public class FileController : Controller
{
private readonly IGridFsRepository _gridFsManager;
public FileController(IGridFsRepository gridFsRepository)
{
_gridFsManager = gridFsRepository;
}
[AllowAnonymous]
[HttpGet("{fileName}",Name = "GetByFileName")]
public async Task<IActionResult> GetByFileName(string fileName)
{
return Ok(await _gridFsManager.DownloadAsync(fileName));
}
[AllowAnonymous]
[HttpGet("{id}",Name = "GetById")]
public async Task<IActionResult> GetByFileName(ObjectId id)
{
return Ok(await _gridFsManager.DownloadAsync(id));
}
[HttpPost]
public async Task<IActionResult> Upload([FromForm] IFormFile file)
{
if (file != null)
{
if (file.ContentType.Contains("image"))
return BadRequest("Sorry only image jpg/jpeg/png
accepted");
if (file.Length >= (300 * 1024))
return BadRequest($"Sorry {file.FileName} is exceeds
300kb");
await _gridFsManager.DeleteAsync(file.FileName);
await _gridFsManager.UploadAsync(file);
}
return NoContent();
}
[HttpDelete]
public async Task<IActionResult> Delete(string id)
{
await _gridFsManager.DeleteAsync(id);
return NoContent();
}
}
please do not forget to resolve dependency:
services.AddScoped<IGridFsRepository, GridFsRepository>();
to file from html:
<div class="btn">
<span>Logo</span>
<input type="file" data-ng-model="cp.data.file"
id="selectedFile" name="selectedFile">
</div>
lets go to UI layer:
first create an angular factory:
(function () {
"use strict";
angular.module("appCdn", [])
.factory('fileUploader', ["$http", function ($http) {
return {
upload: function (url, file, fileMaxSize, fileName, callback) {
if (this.isValidFileSize(fileMaxSize, file)) {
var fd = new FormData(); //Create FormData object
if (fileName)
fd.append("file", file, fileName);
else
fd.append("file", file);
$http.post(url, fd, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
}).success(function (data) {
callback();
}).error(function (data) {
Materialize.toast("Sorry! error in file upload", 4000, 'red');
});
} else {
Materialize.toast("Sorry! " + file.name + " exceeds 300kb", 4000, 'red');
}
},
isValidFileSize: function (maximumAllowedSize, file) {
if (file.size >= maximumAllowedSize) {
return false;
} else {
return true;
}
}
};
}
]);
})();
after that create an angular controller:
angular.module('ecom').controller('companyProfileCtrl',
['$http', 'config', "confirmation", "fileUploader",companyProfile]);
function companyProfile($http, config, confirmation, fileUploader) {
var vm = this; vm.getProfile = function () {
$http.get(config.apiUrl + "companyProfile")
.success(function (response) {
vm.data = response;
});
};
vm.save = function (profile) {
confirmation.confirm(function () {
$http.post(config.apiUrl + "companyProfile", profile)
.success(function (data) {
var fileName = "";
if (profile.id) {
fileName = profile.id;
} else {
fileName = data;
}
vm.upload(fileName,
function () {
Materialize.toast("succeeded", 4000, 'green');
window.location.href = window.history.back();
});
})
.error(function (data) {
Materialize.toast(data, 4000, 'red');
});
});
};
vm.upload = function (fileName, callback) {
var photo = document.getElementById("selectedFile");
var file = photo.files[0];
if (file) {fileUploader.upload(config.cdnUrl + "files",
//300kb
file, 1024 * 300, fileName, callback);
}
};
};
finally to show the image in html:
<div><img src="http://localhost:41792/api/files/{{cp.data.id}}"
class="img-responsive visible-md visible-lg img-margin-desktop"
width="350" height="167" />
</div>
finally we done this. this is all.
I always looking forward to receiving criticism.

Ionic Local storage put information into array

Here is the code
Controller.js
$scope.addFavorite = function (index) {
$scope.temp = {
id: index
};
$scope.dish = $localStorage.getObject('favorites', '{}');
console.log($localStorage.get('favorites'));
$localStorage.storeObject('favorites', JSON.stringify($scope.temp));
var favorites = $localStorage.getObject('favorites');
console.log(favorites);
favoriteFactory.addToFavorites(index);
$ionicListDelegate.closeOptionButtons();
}
Service.js
.factory('favoriteFactory', ['$resource', 'baseURL', function ($resource, baseURL) {
var favFac = {};
var favorites = [];
favFac.addToFavorites = function (index) {
for (var i = 0; i < favorites.length; i++) {
if (favorites[i].id == index)
return;
}
favorites.push({id: index});
};
favFac.deleteFromFavorites = function (index) {
for (var i = 0; i < favorites.length; i++) {
if (favorites[i].id == index) {
favorites.splice(i, 1);
}
}
}
favFac.getFavorites = function () {
return favorites;
};
return favFac;
}])
.factory('$localStorage', ['$window', function($window) {
return {
store: function(key, value) {
$window.localStorage[key] = value;
},
get: function(key, defaultValue) {
return $window.localStorage[key] || defaultValue;
},
storeObject: function(key, value) {
$window.localStorage[key] = JSON.stringify(value);
},
getObject: function(key,defaultValue) {
return JSON.parse($window.localStorage[key] || defaultValue);
}
}
}])
I want to make a Favorites function, and I want to put every item's ID that marked into an array.
But, it couldn't expand the array and only change the value.
Did I make something wrong on here? Or maybe I put a wrong method on here?
Thank you in advance!
I just create logic for storing object, you have to made logic for remove object from localstorage.
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS</title>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script>document.write('<base href="' + document.location + '" />');</script>
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="item in items">
{{item.item_name}}
<button ng-click="addFavorite(item.id)">Add to Favorite</button>
<br><hr>
</div>
</body>
</html>
<script type="text/javascript">
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope,$http)
{
$scope.items = [
{id:1,item_name:'Apple'},
{id:2,item_name:'Banana'},
{id:3,item_name:'Grapes'},
]
$scope.addFavorite = function (index)
{
if(localStorage.getItem('favorites')!=undefined)
{
var old_favorite = JSON.parse(localStorage.getItem('favorites'));
var obj = {index:index};
old_favorite.push(obj);
localStorage.setItem('favorites',JSON.stringify(old_favorite));
}
else
{
var obj = [{index:index}];
localStorage.setItem('favorites',JSON.stringify(obj));
}
}
});
</script>