I'm making an example with flutter and I've come across a question mark. In my project I have implemented dependency injection and I have two classes to get data one for production and testing with local data (Mock). The problem is that the local data I have stored in a json file and when I implement the functionality "fetchProducts" I do not know how to get the Context to load the json... I hope you can help me, thanks.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:graphqllapp/data/product_data.dart';
import 'package:path/path.dart';
class MockProductRepository implements ProductRepository {
#override
Future<List<Product>> fetchProducts() async {
// TODO: implement fetchUsers
String data = await
DefaultAssetBundle.of(????).loadString("mockdata/data.json");
var jsonResult = json.decode(data);
return new Future.value(products);
}
}
You can instead use rootBundle which is the default value of DefaultAssetBundle
rootBundle.loadString("mockdata/data.json");
Related
I'm using Injectable and I have two classes. WebImageDownloader and MobileImageDownloader. Both are implementing ImageDownloader which is an abstract class. I'm registering web and mobile image downloaders as ImageDownloader with Injectable, one registered under web, one under mobile environment.
But since WebImageDownloader has dart:js and dart:html imports, I can't run my code. Because these libraries are not found.
I see on some answers that people do conditional imports between dart:io and dart:html but it doesn't work for me.
Also, the question is under issues for Injectable.
import 'MobileFileDownloader.dart'
if (dart.library.html) 'WebFileDownloadService.dart';
abstract class NativeFileDownloader {
void downloadFile(List<int> bytes, String downloadName);
factory NativeFileDownloader() =>getDownloader();
}
import 'NativeFileDownloader.dart';
class WebFileDownloadService implements NativeFileDownloader{
void downloadFile(List<int> bytes, String downloadName) {
// Encode our file in base64
final _base64 = base64Encode(bytes);
// Create the link with the file
final anchor = AnchorElement(href: 'data:application/octet-stream;base64,$_base64')
..target = 'blank'
..setAttribute('download', downloadName);
// add the name
//anchor.download = downloadName;
// trigger download
document.body?.append(anchor);
anchor.click();
anchor.remove();
return;
}
}
NativeFileDownloader getDownloader()=>WebFileDownloadService();
import 'package:flovo/Services/FileDownloadService/Native/NativeFileDownloader.dart';
class MobileFileDownloader implements NativeFileDownloader{
#override
void downloadFile(List<int> bytes, String downloadName) {
}
}
NativeFileDownloader getDownloader()=>MobileFileDownloader();
use => NativeFileDownloader().downloadFile(list, 'image.jpeg');
How can I use the websocket package with dart web? I have the following code
import 'package:projectname/data/chat/chat_message.dart';
import 'package:projectname/data/chat/chat_provider.dart';
import 'package:web_socket_channel/io.dart';
import '../path.dart';
class MockChatProvider implements ChatProvider {
#override
IOWebSocketChannel connect() {
return IOWebSocketChannel.connect(Uri.parse(Path.joinChat));
}
#override
sendChatMessage(IOWebSocketChannel channel, ChatMessage message) {
channel.sink.add(message.toJson());
}
}
But when I try to connect I get the following error
Unsupported operation: Platform._version
The package does say it supports web. What am I doing wrong?
Just use the package package:web_socket_channel/web_socket_channel.dart
TLDR;
I think you should use this...
import 'package:web_socket_channel/web_socket_channel.dart';
...instead of...
import 'package:web_socket_channel/io.dart';
and use it as
WebSocketChannel connect() {
...
return WebSocketChannel.connect(Uri.parse(Path.joinChat));
...
sendChatMessage(WebSocketChannel channel, ChatMessage message) {
Note: I have not tried and tested it!
I think the problem is that you found the right package, but you're using directly IOWebSocketChannel. That only works on places where dart:io is available. There's another class in that package, HtmlWebSocketChannel that only works on the web.
I think the issue is that you are importing package:web_socket_channel/io.dart for web and you should instead import package:web_socket_channel/web_socket_channel.dart.
Related GitHub issue on package's repo: https://github.com/dart-lang/web_socket_channel/issues/159
I have a simple class like;
import 'dart:io';
class IDCardClass {
File frontImageFile;
File backImageFile;
}
From front_test.dart class I need to assign a data to frontImageFile and back_test.dart class I need to assign a data to backImageFile.
In my home.dart or another ***.dart class I need to get frontImageFile and backImageFile to show it to user.
My question is How can I access global data from another class in Flutter?
Make the variables to static like this:
class IDCardClass {
static File frontImageFile;
static File backImageFile;
}
Just import the class into the other class and access the variables.
import 'package:your_projectname/your_folder/IDCardClass.dart';
.....
var imageFile = IDCardClass.frontImageFile;
.....
I need to display the title and name of all child and grand child pages from given path in JSON format. Please provide the implementation.
First You have to try something yourself, then you call for help, not the complete solution!anyway there are couple of solution down there.
According to Adobe here you can implement page information in JSON format:
package com.adobe.example;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Reference;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageInfoProvider;
#Component(metatype = false)
#Properties({
#Property(name="service.description", value="Returns the public URL of a resource.")
})
#Service
public class PageUrlInfoProvider implements PageInfoProvider {
#Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY)
private com.day.cq.commons.Externalizer externalizer;
private String fetchExternalUrl(ResourceResolver rr, String path) {
return externalizer.publishLink(rr, path);
}
public void updatePageInfo(SlingHttpServletRequest request, JSONObject info, Resource resource)
throws JSONException {
Page page = resource.adaptTo(Page.class);
JSONObject urlinfo = new JSONObject();
urlinfo.put("publishURL", fetchExternalUrl(null,page.getPath()));
info.put("URLs",urlinfo);
}
}
Or you may try this Page for solution
Please refer to below link which may be useful:
http://www.nateyolles.com/blog/2015/12/converting-aem-sling-resources-to-json.
Apart from the above solution you also use recursive level to get the data in the JSON format for example /content/we-retail/language-masters/en.{placeholder}.json
replace the placeholder with the level of nodes you want to print and return back the JSON wherever needed.
To know more about the rendering data in different formats,
Refer: https://sling.apache.org/documentation/bundles/rendering-content-default-get-servlets.html
I implemented workflows, but it would be nice to know if there are hooks provided by the client library which allow to hook in. When a workflow was triggered and finished, a CQ.Notification should be displayed. Or do i need to implement a polling library by myself?
As far as I know, there is no built-in CQ area to see when something is done, aside from looking here:
http://yoursite.com:port/libs/cq/workflow/content/console.html
Once there, you can go to the 'Instances' tab and see what's happening.
In one application that I worked on, we ended up writing our own method that sends notifications to us based on one of our workflows (our workflow ties into it - from the workflow models area, you can set your process to be a servlet that you've put into CQ). Here is the main piece of code from our servlet that catches the process being active, and then calls our methods to email us based on what it finds:
import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.exec.WorkItem;
import com.day.cq.workflow.exec.WorkflowData;
import com.day.cq.workflow.exec.WorkflowProcess;
import com.day.cq.workflow.metadata.MetaDataMap;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import java.util.Arrays;
public class YourServletName implements WorkflowProcess {
#Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException {
session = workflowSession.getSession();
final WorkflowData data = workItem.getWorkflowData();
String type = data.getPayloadType();
String[] argStrings = args.get("PROCESS_ARGS", ARG_UPDATED).split(",");
String reason = argStrings[0];
String baseUrl = argStrings[1];
try {
if (type.equals(TYPE_JCR_PATH) && data.getPayload() != null) {
String resourcePath = data.getPayload().toString();
logger.info("Send Notification that {} has been {}.", resourcePath, reason.toLowerCase());
if (resourcePath != null && !resourcePath.isEmpty()) {
ResourceInfo resourceInfo = new ResourceInfo(resourcePath, baseUrl);
sendEmail(resourceInfo, reason);
}
}
} catch (EmailException ex) {
logger.warn("Failed to send Email");
throw new WorkflowException(ex);
} catch (MailingException ex) {
logger.warn("Failed to send Email");
throw new WorkflowException(ex);
}
}
}
You can find more info in the documentation for Extending Workflow Functionality.
Look at the first code block on that page, and that will give you the best idea of how you can implement a custom workflow handler.
EDIT
If you want to see it on the front-end, you could do an AJAX call to get the JSON list of currently running workflows - you can hit this url:
http://localhost:4502/etc/workflow/instances.RUNNING.json
Then you could loop through them and see if yours is in there. This isn't very nice though, since they are all just listed by IDs. I would instead suggest using the querybuilder, or again, just doing an AJAX GET. This is one example:
1_group.0_path=/etc/workflow/instances
2_group.0_type=cq:Workflow
0_group.property.2_value=COMPLETED
0_group.property=status
0_group.property.and=true
3_group.property=modelId
3_group.property.2_value=/etc/workflow/models/your-model-name/jcr:content/model
3_group.property.and=true
Then the URL would look something like this:
http://yoursiteurl:port/libs/cq/search/content/querydebug.html?_charset_=UTF-8&query=http%3A%2F%2Fyoursiteurl%3Aport%3F%0D%0A1_group.0_path%3D%2Fetc%2Fworkflow%2Finstances%0D%0A2_group.0_type%3Dcq%3AWorkflow%0D%0A0_group.property.2_value%3DRUNNING%0D%0A0_group.property%3Dstatus%0D%0A0_group.property.and%3Dtrue%0D%0A3_group.property%3DmodelId%0D%0A3_group.property.2_value%3D%2Fetc%2Fworkflow%2Fmodels%2Fyour-model-name%2Fjcr%3Acontent%2Fmodel%0D%0A3_group.property.and%3Dtrue
It's ugly, but it gets you the results you need, and then you can parse them to get further information you need.