I generated a list of strings dynamically.
/
/I declared a list of strings and generated it using the length of my product.
late final List<String> recovered;
//the length of the products is 3
recovered = List.generate(products.length, (index) => ""));
//I assigned the list generated to the onChanged method inside my TextField.
TextField(
onChanged: (value) {
recovered[index] =
value;
log("the value is $value");
setState(() {});
},
}),
I want to get each String generated and assigned to a map dynamically. Like this:
{"product": "Noodles", "recovered": "2"} //recovered is the string from the text field, the product is gotten from the list of products.
I can't use recovered[index] because it returns the string at the first index only. I can't do this recovered[1] because since the string is generated dynamically, I can't get each index.
I figured out a solution that works.
List<Map> mapList = []; //Create a list of map
var myproduct = {}; //a map that will take the product and the recovered.
Then assigned the myproduct to the list of map (mapList) inside the TextField.
TextField(
onChanged: (value) {
recovered[index] =
value;
myproduct = {
"product": products[index]['product'], "quantity_delivered": value
}; mapList.add(myproduct);
}),
Related
I had received two values as parameters of a function and now I have to use that values out of that function but i am receiving null values for those values.
String title;
String type;
void _addNewMedicine(String medTitle, String medType) {
title = medTitle; // the value of medTitle is assigned to title
type = medType; // the value of medType is assigned to type
final newMed = Items(productname: medTitle, type: medType);
setState(() {
_userMedicine.add(newMed);
},
);
}
If I used print(medTitle) or print(medType) then the output is null.
So please someone help!!!
Thank you in advance...
Move your assignment statements into the setState function so the state rebuilds. Without rebuilding the state other widgets and functions will use the old values.
setState(
() {
title = medTitle; // the value of medTitle is assigned to title
type = medType;
_userMedicine.add(newMed);
},
);
I am using a LIKE query to show results from the Posts table where the category field matches one of the array elements in the Users table's skills field. But it is not giving me any results.
Controller
class TaskerController extends Controller
{
public function index()
{
return view('index');
}
public function tasks()
{
$skills = Auth::user()->skills;
$posts = Post::where('category', 'LIKE', '%'.$skills.'%');
return view('task')->with('posts', $posts);
}
}
You can not concatenate array like a string.
Since your skills is an array use whereIn method
public function tasks(){
$skills = Auth::user()->skills;
$skills = explode (",", $skills); // since you got comma separated skills you need to convert to array
//$skills =['skill1', 'skill2', 'skill3'];
$posts = Post::whereIn('category', $skills );
return view('task')->with('posts', $posts);
}
In python, I often use strings as templates, e.g.
templateUrl = '{host}/api/v3/{container}/{resourceid}'
params = {'host': 'www.api.com', 'container': 'books', 'resourceid': 10}
api.get(templateUrl.format(**params))
This allows for easy base class setup and the like. How can I do the same in dart?
I'm assuming I will need to create a utility function to parse the template and substitute manually but really hoping there is something ready to use.
Perhaps a TemplateString class with a format method that takes a Map of name/value pairs to substitute into the string.
Note: the objective is to have a generic "format" or "interpolation" function that doesn't need to know in advance what tags or names will exist in the template.
Further clarification: the templates themselves are not resolved when they are set up. Specifically, the template is defined in one place in the code and then used in many other places.
Dart does not have a generic template string functionality that would allow you to insert values into your template at runtime.
Dart only allows you to interpolate strings with variables using the $ syntax in strings, e.g. var string = '$domain/api/v3/${actions.get}'. You would need to have all the variables defined in your code beforehand.
However, you can easily create your own implementation.
Implementation
You pretty much explained how to do it in your question yourself: you pass a map and use it to have generic access to the parameters using the [] operator.
To convert the template string into something that is easy to access, I would simply create another List containing fixed components, like /api/v3/ and another Map that holds generic components with their name and their position in the template string.
class TemplateString {
final List<String> fixedComponents;
final Map<int, String> genericComponents;
int totalComponents;
TemplateString(String template)
: fixedComponents = <String>[],
genericComponents = <int, String>{},
totalComponents = 0 {
final List<String> components = template.split('{');
for (String component in components) {
if (component == '') continue; // If the template starts with "{", skip the first element.
final split = component.split('}');
if (split.length != 1) {
// The condition allows for template strings without parameters.
genericComponents[totalComponents] = split.first;
totalComponents++;
}
if (split.last != '') {
fixedComponents.add(split.last);
totalComponents++;
}
}
}
String format(Map<String, dynamic> params) {
String result = '';
int fixedComponent = 0;
for (int i = 0; i < totalComponents; i++) {
if (genericComponents.containsKey(i)) {
result += '${params[genericComponents[i]]}';
continue;
}
result += fixedComponents[fixedComponent++];
}
return result;
}
}
Here would be an example usage, I hope that the result is what you expected:
main() {
final templateUrl = TemplateString('{host}/api/v3/{container}/{resourceid}');
final params = <String, dynamic>{'host': 'www.api.com', 'container': 'books', 'resourceid': 10};
print(templateUrl.format(params)); // www.api.com/api/v3/books/10
}
Here it is as a Gist.
Here is my solution:
extension StringFormating on String {
String format(List<String> values) {
int index = 0;
return replaceAllMapped(new RegExp(r'{.*?}'), (_) {
final value = values[index];
index++;
return value;
});
}
String formatWithMap(Map<String, String> mappedValues) {
return replaceAllMapped(new RegExp(r'{(.*?)}'), (match) {
final mapped = mappedValues[match[1]];
if (mapped == null)
throw ArgumentError(
'$mappedValues does not contain the key "${match[1]}"');
return mapped;
});
}
}
This gives you a very similar functionality to what python offers:
"Test {} with {}!".format(["it", "foo"]);
"Test {a} with {b}!".formatWithMap({"a": "it", "b": "foo"})
both return "Test it with foo!"
It's even more easy in Dart. Sample code below :
String host = "www.api.com"
String container = "books"
int resourceId = 10
String templateUrl = "$host/api/v3/$container/${resourceId.toString()}"
With the map, you can do as follows :
Map<String, String> params = {'host': 'www.api.com', 'container': 'books', 'resourceid': 10}
String templateUrl = "${params['host']}/api/v3/${params['container']}/${params['resourceId']}"
Note : The above code defines Map as <String, String>. You might want <String, Dynamic> (and use .toString())
Wouldn't it be simplest to just make it a function with named arguments? You could add some input validation if you wanted to.
String templateUrl({String host = "", String container = "", int resourceid = 0 }) {
return "$host/api/v3/$container/$resourceId";
}
void main() {
api.get(templateUrl(host:"www.api.com", container:"books", resourceid:10));
}
I have a list of integers say
var items = new[] { 1, 2, 3, 4 };
I would like to cast them to list of strings. The reason is i need the set to be appear like
{<- 1 -> , <-2-> ,<-3-> ,<-4-> }
Normally i create another list like
List<string> list = new List<string>();
foreach (int i in items)
{
list.Add("<-" + i + "->");
}
Is there any shortcut to achieve the same result?
You could use LINQ and more specifically a combination of the .Select() and .ToList() extension methods:
var items = new[] { 1, 2, 3, 4 };
List<string> list = items.Select(i => string.Format("<-{0}->", i)).ToList();
The .Select() extension method projects each integer element to the corresponding string representation and the .ToList() extension method casts the result to a List<string>.
Try
var lst = items.ToList().ConvertAll(x=>x.ToString()).Select(x=>"<-"+ x+"->");
Is there a way to programmatically access the Label & Value fields that has been created as a custom Field in MS CRM Dynamics please?
I have added a custom field called "new_producttypesubcode" which, for example, has 2 options, Trophy = 1000000 and Kit = 10000001.
I am writing an import utility that mirrors products between the customers website and their CRM and I want to get a list of all possible product options in the CRM to see if they are matched in the website.
So, in essence I want to...
get the list of possible new_producttypesubcodes and their corresponding values.
Iterate through the product variants in the website.
if the product variant name matches any name in the list of new_producttypecodes then add the value 1000000
So, if I find a product added to the website and its marked as a "Trophy" and "Trophy" exists in the CRM then new OptionSetValue(100000001)
I hope that makes sense...
Thanks
This function retrieves a dictionary of possible values localised to the current user. Taken from: CRM 2011 Programatically Finding the Values of Picklists, Optionsets, Statecode, Statuscode and Boolean (Two Options).
static Dictionary<String, int> GetNumericValues(IOrganizationService service, String entity, String attribute)
{
RetrieveAttributeRequest request = new RetrieveAttributeRequest
{
EntityLogicalName = entity,
LogicalName = attribute,
RetrieveAsIfPublished = true
};
RetrieveAttributeResponse response = (RetrieveAttributeResponse)service.Execute(request);
switch (response.AttributeMetadata.AttributeType)
{
case AttributeTypeCode.Picklist:
case AttributeTypeCode.State:
case AttributeTypeCode.Status:
return ((EnumAttributeMetadata)response.AttributeMetadata).OptionSet.Options
.ToDictionary(key => key.Label.UserLocalizedLabel.Label, option => option.Value.Value);
case AttributeTypeCode.Boolean:
Dictionary<String, int> values = new Dictionary<String, int>();
BooleanOptionSetMetadata metaData = ((BooleanAttributeMetadata)response.AttributeMetadata).OptionSet;
values[metaData.TrueOption.Label.UserLocalizedLabel.Label] = metaData.TrueOption.Value.Value;
values[metaData.FalseOption.Label.UserLocalizedLabel.Label] = metaData.FalseOption.Value.Value;
return values;
default:
throw new ArgumentOutOfRangeException();
}
}
So you would then need to do something like:
Dictionary<String, int> values = GetNumericValues(proxy, "your_entity", "new_producttypesubcode");
if(values.ContainsKey("Trophy"))
{
//Do something with the value
OptionSetValue optionSetValue = values["Trophy"];
int value = optionSetValue.Value;
}
Yes, that data is all stored in the metadata for an attribute (SDK article). You have to retrieve the entity metadata for the entity and then find the attribute in the list. Then cast that attribute to a PicklistAttributeMetadata object and it will contain a list of options. I would mention that typically retrieving Metadata from CRM is an expensive operation, so think about caching.
private static OptionSetMetadata RetrieveOptionSet(IOrganizationService orgService,
string entityName, string attributeName)
{
var entityResponse = (RetrieveEntityResponse)orgService.Execute(
new RetrieveEntityRequest
{ LogicalName = entityName, EntityFilters = EntityFilters.Attributes });
var entityMetadata = entityResponse.EntityMetadata;
for (int i = 0; i < entityMetadata.Attributes.Length; i++)
{
if (attributeName.Equals(entityMetadata.Attributes[i].LogicalName))
{
if (entityMetadata.Attributes[i].AttributeType.Value ==
AttributeTypeCode.Picklist)
{
var attributeMD = (PicklistAttributeMetadata)
entityMetadata.Attributes[i];
return attributeMD.OptionSet;
}
}
}
return null;
}
Here is how to write the options to the console using the above call.
var optionSetMD = RetrieveOptionSet(orgService, "account", "accountcategorycode");
var options = optionSetMD.Options;
for (int i = 0; i < options.Count; i++)
{
Console.WriteLine("Local Label: {0}. Value: {1}",
options[i].Label.UserLocalizedLabel.Label,
options[i].Value.HasValue ? options[i].Value.Value.ToString() : "null");
}
I believe this works for global option set attributes as well, but if you know it is a global option set there is a different message for it that would probably a bit more efficient (SDK article).